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