Line data Source code
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 *
782 : get_implementation (void)
783 : {
784 : #ifndef TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR
785 22 : if (!global_implementation)
786 1 : global_implementation = _pixman_choose_implementation ();
787 : #endif
788 22 : 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
850 : pixman_list_init (pixman_list_t *list)
851 : {
852 0 : list->head = (pixman_link_t *)list;
853 0 : list->tail = (pixman_link_t *)list;
854 : }
855 :
856 : static force_inline void
857 : pixman_list_prepend (pixman_list_t *list, pixman_link_t *link)
858 : {
859 0 : link->next = list->head;
860 0 : link->prev = (pixman_link_t *)list;
861 0 : list->head->prev = link;
862 0 : list->head = link;
863 : }
864 :
865 : static force_inline void
866 : pixman_list_unlink (pixman_link_t *link)
867 : {
868 0 : link->prev->next = link->next;
869 0 : link->next->prev = link->prev;
870 : }
871 :
872 : static force_inline void
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
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 0 : a = (s >> 3) & 0x1F001F;
915 0 : b = s & 0xFC00;
916 0 : a |= a >> 5;
917 0 : a |= b >> 5;
918 0 : return (uint16_t)a;
919 : }
920 :
921 : static force_inline uint32_t
922 : convert_0565_to_0888 (uint16_t s)
923 : {
924 0 : return (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) |
925 0 : ((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) |
926 0 : ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)));
927 : }
928 :
929 : static force_inline uint32_t
930 : convert_0565_to_8888 (uint16_t s)
931 : {
932 0 : return convert_0565_to_0888 (s) | 0xff000000;
933 : }
934 :
935 : /* Trivial versions that are useful in macros */
936 :
937 : static force_inline uint32_t
938 : convert_8888_to_8888 (uint32_t s)
939 : {
940 0 : return s;
941 : }
942 :
943 : static force_inline uint32_t
944 : convert_x888_to_8888 (uint32_t s)
945 : {
946 0 : return s | 0xff000000;
947 : }
948 :
949 : static force_inline uint16_t
950 : convert_0565_to_0565 (uint16_t s)
951 : {
952 0 : 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
971 : unorm_to_unorm (uint32_t val, int from_bits, int to_bits)
972 : {
973 : uint32_t result;
974 :
975 0 : if (from_bits == 0)
976 0 : return 0;
977 :
978 : /* Delete any extra bits */
979 0 : val &= ((1 << from_bits) - 1);
980 :
981 0 : if (from_bits >= to_bits)
982 0 : return val >> (from_bits - to_bits);
983 :
984 : /* Start out with the high bit of val in the high bit of result. */
985 0 : 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 0 : REPLICATE();
1005 0 : REPLICATE();
1006 0 : REPLICATE();
1007 0 : REPLICATE();
1008 0 : REPLICATE();
1009 :
1010 0 : 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
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 */
|