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