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_ARM_IWMMXT || 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_MIPS_DSPR2
644 pixman_implementation_t *
645 _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback);
646 #endif
647
648 #ifdef USE_VMX
649 pixman_implementation_t *
650 _pixman_implementation_create_vmx (pixman_implementation_t *fallback);
651 #endif
652
653 pixman_bool_t
654 _pixman_implementation_disabled (const char *name);
655
656 pixman_implementation_t *
657 _pixman_x86_get_implementations (pixman_implementation_t *imp);
658
659 pixman_implementation_t *
660 _pixman_arm_get_implementations (pixman_implementation_t *imp);
661
662 pixman_implementation_t *
663 _pixman_ppc_get_implementations (pixman_implementation_t *imp);
664
665 pixman_implementation_t *
666 _pixman_mips_get_implementations (pixman_implementation_t *imp);
667
668 pixman_implementation_t *
669 _pixman_choose_implementation (void);
670
671 pixman_bool_t
672 _pixman_disabled (const char *name);
673
674
675 /*
676 * Utilities
677 */
678 pixman_bool_t
679 _pixman_compute_composite_region32 (pixman_region32_t * region,
680 pixman_image_t * src_image,
681 pixman_image_t * mask_image,
682 pixman_image_t * dest_image,
683 int32_t src_x,
684 int32_t src_y,
685 int32_t mask_x,
686 int32_t mask_y,
687 int32_t dest_x,
688 int32_t dest_y,
689 int32_t width,
690 int32_t height);
691 uint32_t *
692 _pixman_iter_get_scanline_noop (pixman_iter_t *iter, const uint32_t *mask);
693
694 void
695 _pixman_iter_init_bits_stride (pixman_iter_t *iter, const pixman_iter_info_t *info);
696
697 /* These "formats" all have depth 0, so they
698 * will never clash with any real ones
699 */
700 #define PIXMAN_null PIXMAN_FORMAT (0, 0, 0, 0, 0, 0)
701 #define PIXMAN_solid PIXMAN_FORMAT (0, 1, 0, 0, 0, 0)
702 #define PIXMAN_pixbuf PIXMAN_FORMAT (0, 2, 0, 0, 0, 0)
703 #define PIXMAN_rpixbuf PIXMAN_FORMAT (0, 3, 0, 0, 0, 0)
704 #define PIXMAN_unknown PIXMAN_FORMAT (0, 4, 0, 0, 0, 0)
705 #define PIXMAN_any PIXMAN_FORMAT (0, 5, 0, 0, 0, 0)
706
707 #define PIXMAN_OP_any (PIXMAN_N_OPERATORS + 1)
708
709 #define FAST_PATH_ID_TRANSFORM (1 << 0)
710 #define FAST_PATH_NO_ALPHA_MAP (1 << 1)
711 #define FAST_PATH_NO_CONVOLUTION_FILTER (1 << 2)
712 #define FAST_PATH_NO_PAD_REPEAT (1 << 3)
713 #define FAST_PATH_NO_REFLECT_REPEAT (1 << 4)
714 #define FAST_PATH_NO_ACCESSORS (1 << 5)
715 #define FAST_PATH_NARROW_FORMAT (1 << 6)
716 #define FAST_PATH_COMPONENT_ALPHA (1 << 8)
717 #define FAST_PATH_SAMPLES_OPAQUE (1 << 7)
718 #define FAST_PATH_UNIFIED_ALPHA (1 << 9)
719 #define FAST_PATH_SCALE_TRANSFORM (1 << 10)
720 #define FAST_PATH_NEAREST_FILTER (1 << 11)
721 #define FAST_PATH_HAS_TRANSFORM (1 << 12)
722 #define FAST_PATH_IS_OPAQUE (1 << 13)
723 #define FAST_PATH_NO_NORMAL_REPEAT (1 << 14)
724 #define FAST_PATH_NO_NONE_REPEAT (1 << 15)
725 #define FAST_PATH_X_UNIT_POSITIVE (1 << 16)
726 #define FAST_PATH_AFFINE_TRANSFORM (1 << 17)
727 #define FAST_PATH_Y_UNIT_ZERO (1 << 18)
728 #define FAST_PATH_BILINEAR_FILTER (1 << 19)
729 #define FAST_PATH_ROTATE_90_TRANSFORM (1 << 20)
730 #define FAST_PATH_ROTATE_180_TRANSFORM (1 << 21)
731 #define FAST_PATH_ROTATE_270_TRANSFORM (1 << 22)
732 #define FAST_PATH_SAMPLES_COVER_CLIP_NEAREST (1 << 23)
733 #define FAST_PATH_SAMPLES_COVER_CLIP_BILINEAR (1 << 24)
734 #define FAST_PATH_BITS_IMAGE (1 << 25)
735 #define FAST_PATH_SEPARABLE_CONVOLUTION_FILTER (1 << 26)
736
737 #define FAST_PATH_PAD_REPEAT \
738 (FAST_PATH_NO_NONE_REPEAT | \
739 FAST_PATH_NO_NORMAL_REPEAT | \
740 FAST_PATH_NO_REFLECT_REPEAT)
741
742 #define FAST_PATH_NORMAL_REPEAT \
743 (FAST_PATH_NO_NONE_REPEAT | \
744 FAST_PATH_NO_PAD_REPEAT | \
745 FAST_PATH_NO_REFLECT_REPEAT)
746
747 #define FAST_PATH_NONE_REPEAT \
748 (FAST_PATH_NO_NORMAL_REPEAT | \
749 FAST_PATH_NO_PAD_REPEAT | \
750 FAST_PATH_NO_REFLECT_REPEAT)
751
752 #define FAST_PATH_REFLECT_REPEAT \
753 (FAST_PATH_NO_NONE_REPEAT | \
754 FAST_PATH_NO_NORMAL_REPEAT | \
755 FAST_PATH_NO_PAD_REPEAT)
756
757 #define FAST_PATH_STANDARD_FLAGS \
758 (FAST_PATH_NO_CONVOLUTION_FILTER | \
759 FAST_PATH_NO_ACCESSORS | \
760 FAST_PATH_NO_ALPHA_MAP | \
761 FAST_PATH_NARROW_FORMAT)
762
763 #define FAST_PATH_STD_DEST_FLAGS \
764 (FAST_PATH_NO_ACCESSORS | \
765 FAST_PATH_NO_ALPHA_MAP | \
766 FAST_PATH_NARROW_FORMAT)
767
768 #define SOURCE_FLAGS(format) \
769 (FAST_PATH_STANDARD_FLAGS | \
770 ((PIXMAN_ ## format == PIXMAN_solid) ? \
771 0 : (FAST_PATH_SAMPLES_COVER_CLIP_NEAREST | FAST_PATH_NEAREST_FILTER | FAST_PATH_ID_TRANSFORM)))
772
773 #define MASK_FLAGS(format, extra) \
774 ((PIXMAN_ ## format == PIXMAN_null) ? 0 : (SOURCE_FLAGS (format) | extra))
775
776 #define FAST_PATH(op, src, src_flags, mask, mask_flags, dest, dest_flags, func) \
777 PIXMAN_OP_ ## op, \
778 PIXMAN_ ## src, \
779 src_flags, \
780 PIXMAN_ ## mask, \
781 mask_flags, \
782 PIXMAN_ ## dest, \
783 dest_flags, \
784 func
785
786 #define PIXMAN_STD_FAST_PATH(op, src, mask, dest, func) \
787 { FAST_PATH ( \
788 op, \
789 src, SOURCE_FLAGS (src), \
790 mask, MASK_FLAGS (mask, FAST_PATH_UNIFIED_ALPHA), \
791 dest, FAST_PATH_STD_DEST_FLAGS, \
792 func) }
793
794 #define PIXMAN_STD_FAST_PATH_CA(op, src, mask, dest, func) \
795 { FAST_PATH ( \
796 op, \
797 src, SOURCE_FLAGS (src), \
798 mask, MASK_FLAGS (mask, FAST_PATH_COMPONENT_ALPHA), \
799 dest, FAST_PATH_STD_DEST_FLAGS, \
800 func) }
801
802 extern pixman_implementation_t *global_implementation;
803
804 static force_inline pixman_implementation_t *
get_implementation(void)805 get_implementation (void)
806 {
807 #ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
808 if (!global_implementation)
809 global_implementation = _pixman_choose_implementation ();
810 #endif
811 return global_implementation;
812 }
813
814 /* This function is exported for the sake of the test suite and not part
815 * of the ABI.
816 */
817 PIXMAN_EXPORT pixman_implementation_t *
818 _pixman_internal_only_get_implementation (void);
819
820 /* Memory allocation helpers */
821 void *
822 pixman_malloc_ab (unsigned int n, unsigned int b);
823
824 void *
825 pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
826
827 void *
828 pixman_malloc_ab_plus_c (unsigned int a, unsigned int b, unsigned int c);
829
830 pixman_bool_t
831 _pixman_multiply_overflows_size (size_t a, size_t b);
832
833 pixman_bool_t
834 _pixman_multiply_overflows_int (unsigned int a, unsigned int b);
835
836 pixman_bool_t
837 _pixman_addition_overflows_int (unsigned int a, unsigned int b);
838
839 /* Compositing utilities */
840 void
841 pixman_expand_to_float (argb_t *dst,
842 const uint32_t *src,
843 pixman_format_code_t format,
844 int width);
845
846 void
847 pixman_contract_from_float (uint32_t *dst,
848 const argb_t *src,
849 int width);
850
851 /* Region Helpers */
852 pixman_bool_t
853 pixman_region32_copy_from_region16 (pixman_region32_t *dst,
854 pixman_region16_t *src);
855
856 pixman_bool_t
857 pixman_region16_copy_from_region32 (pixman_region16_t *dst,
858 pixman_region32_t *src);
859
860 /* Doubly linked lists */
861 typedef struct pixman_link_t pixman_link_t;
862 struct pixman_link_t
863 {
864 pixman_link_t *next;
865 pixman_link_t *prev;
866 };
867
868 typedef struct pixman_list_t pixman_list_t;
869 struct pixman_list_t
870 {
871 pixman_link_t *head;
872 pixman_link_t *tail;
873 };
874
875 static force_inline void
pixman_list_init(pixman_list_t * list)876 pixman_list_init (pixman_list_t *list)
877 {
878 list->head = (pixman_link_t *)list;
879 list->tail = (pixman_link_t *)list;
880 }
881
882 static force_inline void
pixman_list_prepend(pixman_list_t * list,pixman_link_t * link)883 pixman_list_prepend (pixman_list_t *list, pixman_link_t *link)
884 {
885 link->next = list->head;
886 link->prev = (pixman_link_t *)list;
887 list->head->prev = link;
888 list->head = link;
889 }
890
891 static force_inline void
pixman_list_unlink(pixman_link_t * link)892 pixman_list_unlink (pixman_link_t *link)
893 {
894 link->prev->next = link->next;
895 link->next->prev = link->prev;
896 }
897
898 static force_inline void
pixman_list_move_to_front(pixman_list_t * list,pixman_link_t * link)899 pixman_list_move_to_front (pixman_list_t *list, pixman_link_t *link)
900 {
901 pixman_list_unlink (link);
902 pixman_list_prepend (list, link);
903 }
904
905 /* Misc macros */
906
907 #ifndef FALSE
908 # define FALSE 0
909 #endif
910
911 #ifndef TRUE
912 # define TRUE 1
913 #endif
914
915 #ifndef MIN
916 # define MIN(a, b) ((a < b) ? a : b)
917 #endif
918
919 #ifndef MAX
920 # define MAX(a, b) ((a > b) ? a : b)
921 #endif
922
923 /* Integer division that rounds towards -infinity */
924 #define DIV(a, b) \
925 ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \
926 ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
927
928 /* Modulus that produces the remainder wrt. DIV */
929 #define MOD(a, b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
930
931 #define CLIP(v, low, high) ((v) < (low) ? (low) : ((v) > (high) ? (high) : (v)))
932
933 #define FLOAT_IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN)
934
935 /* Conversion between 8888 and 0565 */
936
937 static force_inline uint16_t
convert_8888_to_0565(uint32_t s)938 convert_8888_to_0565 (uint32_t s)
939 {
940 /* The following code can be compiled into just 4 instructions on ARM */
941 uint32_t a, b;
942 a = (s >> 3) & 0x1F001F;
943 b = s & 0xFC00;
944 a |= a >> 5;
945 a |= b >> 5;
946 return (uint16_t)a;
947 }
948
949 static force_inline uint32_t
convert_0565_to_0888(uint16_t s)950 convert_0565_to_0888 (uint16_t s)
951 {
952 return (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) |
953 ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) |
954 ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)));
955 }
956
957 static force_inline uint32_t
convert_0565_to_8888(uint16_t s)958 convert_0565_to_8888 (uint16_t s)
959 {
960 return convert_0565_to_0888 (s) | 0xff000000;
961 }
962
963 /* Trivial versions that are useful in macros */
964
965 static force_inline uint32_t
convert_8888_to_8888(uint32_t s)966 convert_8888_to_8888 (uint32_t s)
967 {
968 return s;
969 }
970
971 static force_inline uint32_t
convert_x888_to_8888(uint32_t s)972 convert_x888_to_8888 (uint32_t s)
973 {
974 return s | 0xff000000;
975 }
976
977 static force_inline uint16_t
convert_0565_to_0565(uint16_t s)978 convert_0565_to_0565 (uint16_t s)
979 {
980 return s;
981 }
982
983 #define PIXMAN_FORMAT_IS_WIDE(f) \
984 (PIXMAN_FORMAT_A (f) > 8 || \
985 PIXMAN_FORMAT_R (f) > 8 || \
986 PIXMAN_FORMAT_G (f) > 8 || \
987 PIXMAN_FORMAT_B (f) > 8 || \
988 PIXMAN_FORMAT_TYPE (f) == PIXMAN_TYPE_ARGB_SRGB)
989
990 #ifdef WORDS_BIGENDIAN
991 # define SCREEN_SHIFT_LEFT(x,n) ((x) << (n))
992 # define SCREEN_SHIFT_RIGHT(x,n) ((x) >> (n))
993 #else
994 # define SCREEN_SHIFT_LEFT(x,n) ((x) >> (n))
995 # define SCREEN_SHIFT_RIGHT(x,n) ((x) << (n))
996 #endif
997
998 static force_inline uint32_t
unorm_to_unorm(uint32_t val,int from_bits,int to_bits)999 unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
1000 {
1001 uint32_t result;
1002
1003 if (from_bits == 0)
1004 return 0;
1005
1006 /* Delete any extra bits */
1007 val &= ((1 << from_bits) - 1);
1008
1009 if (from_bits >= to_bits)
1010 return val >> (from_bits - to_bits);
1011
1012 /* Start out with the high bit of val in the high bit of result. */
1013 result = val << (to_bits - from_bits);
1014
1015 /* Copy the bits in result, doubling the number of bits each time, until
1016 * we fill all to_bits. Unrolled manually because from_bits and to_bits
1017 * are usually known statically, so the compiler can turn all of this
1018 * into a few shifts.
1019 */
1020 #define REPLICATE() \
1021 do \
1022 { \
1023 if (from_bits < to_bits) \
1024 { \
1025 result |= result >> from_bits; \
1026 \
1027 from_bits *= 2; \
1028 } \
1029 } \
1030 while (0)
1031
1032 REPLICATE();
1033 REPLICATE();
1034 REPLICATE();
1035 REPLICATE();
1036 REPLICATE();
1037
1038 return result;
1039 }
1040
1041 uint16_t pixman_float_to_unorm (float f, int n_bits);
1042 float pixman_unorm_to_float (uint16_t u, int n_bits);
1043
1044 /*
1045 * Various debugging code
1046 */
1047
1048 #undef DEBUG
1049
1050 #define COMPILE_TIME_ASSERT(x) \
1051 do { typedef int compile_time_assertion [(x)?1:-1]; } while (0)
1052
1053 /* Turn on debugging depending on what type of release this is
1054 */
1055 #if (((PIXMAN_VERSION_MICRO % 2) == 0) && ((PIXMAN_VERSION_MINOR % 2) == 1))
1056
1057 /* Debugging gets turned on for development releases because these
1058 * are the things that end up in bleeding edge distributions such
1059 * as Rawhide etc.
1060 *
1061 * For performance reasons we don't turn it on for stable releases or
1062 * random git checkouts. (Random git checkouts are often used for
1063 * performance work).
1064 */
1065
1066 # define DEBUG
1067
1068 #endif
1069
1070 void
1071 _pixman_log_error (const char *function, const char *message);
1072
1073 #define return_if_fail(expr) \
1074 do \
1075 { \
1076 if (unlikely (!(expr))) \
1077 { \
1078 _pixman_log_error (FUNC, "The expression " # expr " was false"); \
1079 return; \
1080 } \
1081 } \
1082 while (0)
1083
1084 #define return_val_if_fail(expr, retval) \
1085 do \
1086 { \
1087 if (unlikely (!(expr))) \
1088 { \
1089 _pixman_log_error (FUNC, "The expression " # expr " was false"); \
1090 return (retval); \
1091 } \
1092 } \
1093 while (0)
1094
1095 #define critical_if_fail(expr) \
1096 do \
1097 { \
1098 if (unlikely (!(expr))) \
1099 _pixman_log_error (FUNC, "The expression " # expr " was false"); \
1100 } \
1101 while (0)
1102
1103 /*
1104 * Matrix
1105 */
1106
1107 typedef struct { pixman_fixed_48_16_t v[3]; } pixman_vector_48_16_t;
1108
1109 PIXMAN_EXPORT
1110 pixman_bool_t
1111 pixman_transform_point_31_16 (const pixman_transform_t *t,
1112 const pixman_vector_48_16_t *v,
1113 pixman_vector_48_16_t *result);
1114
1115 PIXMAN_EXPORT
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 PIXMAN_EXPORT
1122 void
1123 pixman_transform_point_31_16_affine (const pixman_transform_t *t,
1124 const pixman_vector_48_16_t *v,
1125 pixman_vector_48_16_t *result);
1126
1127 /*
1128 * Timers
1129 */
1130
1131 #ifdef PIXMAN_TIMERS
1132
1133 static inline uint64_t
oil_profile_stamp_rdtsc(void)1134 oil_profile_stamp_rdtsc (void)
1135 {
1136 uint32_t hi, lo;
1137
1138 __asm__ __volatile__ ("rdtsc\n" : "=a" (lo), "=d" (hi));
1139
1140 return lo | (((uint64_t)hi) << 32);
1141 }
1142
1143 #define OIL_STAMP oil_profile_stamp_rdtsc
1144
1145 typedef struct pixman_timer_t pixman_timer_t;
1146
1147 struct pixman_timer_t
1148 {
1149 int initialized;
1150 const char * name;
1151 uint64_t n_times;
1152 uint64_t total;
1153 pixman_timer_t *next;
1154 };
1155
1156 extern int timer_defined;
1157
1158 void pixman_timer_register (pixman_timer_t *timer);
1159
1160 #define TIMER_BEGIN(tname) \
1161 { \
1162 static pixman_timer_t timer ## tname; \
1163 uint64_t begin ## tname; \
1164 \
1165 if (!timer ## tname.initialized) \
1166 { \
1167 timer ## tname.initialized = 1; \
1168 timer ## tname.name = # tname; \
1169 pixman_timer_register (&timer ## tname); \
1170 } \
1171 \
1172 timer ## tname.n_times++; \
1173 begin ## tname = OIL_STAMP ();
1174
1175 #define TIMER_END(tname) \
1176 timer ## tname.total += OIL_STAMP () - begin ## tname; \
1177 }
1178
1179 #else
1180
1181 #define TIMER_BEGIN(tname)
1182 #define TIMER_END(tname)
1183
1184 #endif /* PIXMAN_TIMERS */
1185
1186 #endif /* __ASSEMBLER__ */
1187
1188 #endif /* PIXMAN_PRIVATE_H */
1189