Changeset 522 for GraphicTest/Packages/Graphics32/GR32_Blend.pas
- Timestamp:
- Apr 17, 2019, 10:42:18 AM (5 years ago)
- Location:
- GraphicTest/Packages/Graphics32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/Graphics32
-
Property svn:ignore
set to
lib
-
Property svn:ignore
set to
-
GraphicTest/Packages/Graphics32/GR32_Blend.pas
r450 r522 41 41 * - 2004/08/25 - ColorDiv 42 42 * 43 * Christian-W. Budde 44 * - 2019/04/01 - Refactoring 45 * 43 46 * ***** END LICENSE BLOCK ***** *) 44 47 … … 48 51 49 52 uses 50 GR32, GR32_ System, GR32_Bindings, SysUtils;53 GR32, GR32_Bindings, SysUtils; 51 54 52 55 var … … 57 60 TBlendReg = function(F, B: TColor32): TColor32; 58 61 TBlendMem = procedure(F: TColor32; var B: TColor32); 62 TBlendMems = procedure(F: TColor32; B: PColor32; Count: Integer); 59 63 TBlendRegEx = function(F, B, M: TColor32): TColor32; 60 64 TBlendMemEx = procedure(F: TColor32; var B: TColor32; M: TColor32); 65 TBlendRegRGB = function(F, B, W: TColor32): TColor32; 66 TBlendMemRGB = procedure(F: TColor32; var B: TColor32; W: TColor32); 67 {$IFDEF TEST_BLENDMEMRGB128SSE4} 68 TBlendMemRGB128 = procedure(F: TColor32; var B: TColor32; W: UInt64); 69 {$ENDIF} 61 70 TBlendLine = procedure(Src, Dst: PColor32; Count: Integer); 62 71 TBlendLineEx = procedure(Src, Dst: PColor32; Count: Integer; M: TColor32); 72 TBlendLine1 = procedure(Src: TColor32; Dst: PColor32; Count: Integer); 63 73 TCombineReg = function(X, Y, W: TColor32): TColor32; 64 74 TCombineMem = procedure(X: TColor32; var Y: TColor32; W: TColor32); … … 74 84 BlendReg: TBlendReg; 75 85 BlendMem: TBlendMem; 86 BlendMems: TBlendMems; 76 87 77 88 BlendRegEx: TBlendRegEx; 78 89 BlendMemEx: TBlendMemEx; 79 90 91 BlendRegRGB: TBlendRegRGB; 92 BlendMemRGB: TBlendMemRGB; 93 {$IFDEF TEST_BLENDMEMRGB128SSE4} 94 BlendMemRGB128: TBlendMemRGB128; 95 {$ENDIF} 96 80 97 BlendLine: TBlendLine; 81 98 BlendLineEx: TBlendLineEx; 99 BlendLine1: TBlendLine1; 82 100 83 101 CombineReg: TCombineReg; … … 93 111 MergeLine: TBlendLine; 94 112 MergeLineEx: TBlendLineEx; 113 MergeLine1: TBlendLine1; 95 114 96 115 { Color algebra functions } … … 105 124 ColorExclusion: TBlendReg; 106 125 ColorScale: TBlendReg; 126 ColorScreen: TBlendReg; 127 ColorDodge: TBlendReg; 128 ColorBurn: TBlendReg; 129 130 { Blended color algebra functions } 131 BlendColorAdd: TBlendReg; 132 BlendColorModulate: TBlendReg; 107 133 108 134 { Special LUT pointers } … … 119 145 { Access to alpha composite functions corresponding to a combine mode } 120 146 147 type 148 PBlendReg = ^TBlendReg; 149 PBlendMem = ^TBlendMem; 150 PBlendRegEx = ^TBlendRegEx; 151 PBlendMemEx = ^TBlendMemEx; 152 PBlendLine = ^TBlendLine; 153 PBlendLineEx = ^TBlendLineEx; 154 155 TBlendRegCombineModeArray = array[TCombineMode] of PBlendReg; 156 TBlendMemCombineModeArray = array[TCombineMode] of PBlendMem; 157 TBlendRegExCombineModeArray = array[TCombineMode] of PBlendRegEx; 158 TBlendMemExCombineModeArray = array[TCombineMode] of PBlendMemEx; 159 TBlendLineCombineModeArray = array[TCombineMode] of PBlendLine; 160 TBlendLineExCombineModeArray = array[TCombineMode] of PBlendLineEx; 161 121 162 const 122 BLEND_REG: array[TCombineMode] of ^TBlendReg= ((@@BlendReg),(@@MergeReg));123 BLEND_MEM: array[TCombineMode] of ^TBlendMem= ((@@BlendMem),(@@MergeMem));124 BLEND_REG_EX: array[TCombineMode] of ^TBlendRegEx= ((@@BlendRegEx),(@@MergeRegEx));125 BLEND_MEM_EX: array[TCombineMode] of ^TBlendMemEx= ((@@BlendMemEx),(@@MergeMemEx));126 BLEND_LINE: array[TCombineMode] of ^TBlendLine= ((@@BlendLine),(@@MergeLine));127 BLEND_LINE_EX: array[TCombineMode] of ^TBlendLineEx= ((@@BlendLineEx),(@@MergeLineEx));163 BLEND_REG: TBlendRegCombineModeArray = ((@@BlendReg),(@@MergeReg)); 164 BLEND_MEM: TBlendMemCombineModeArray = ((@@BlendMem),(@@MergeMem)); 165 BLEND_REG_EX: TBlendRegExCombineModeArray = ((@@BlendRegEx),(@@MergeRegEx)); 166 BLEND_MEM_EX: TBlendMemExCombineModeArray = ((@@BlendMemEx),(@@MergeMemEx)); 167 BLEND_LINE: TBlendLineCombineModeArray = ((@@BlendLine),(@@MergeLine)); 168 BLEND_LINE_EX: TBlendLineExCombineModeArray = ((@@BlendLineEx),(@@MergeLineEx)); 128 169 129 170 var … … 134 175 {$ENDIF} 135 176 136 implementation137 138 {$IFDEF TARGET_x86}139 uses GR32_LowLevel;140 {$ENDIF}141 142 177 var 143 178 RcTable: array [Byte, Byte] of Byte; 144 179 DivTable: array [Byte, Byte] of Byte; 180 181 implementation 182 183 uses 184 GR32_LowLevel, 185 {$IFNDEF PUREPASCAL} 186 GR32_BlendASM, 187 {$IFNDEF OMIT_MMX} 188 GR32_BlendMMX, 189 {$ENDIF} 190 {$IFNDEF OMIT_SSE2} 191 GR32_BlendSSE2, 192 {$ENDIF} 193 {$ENDIF} 194 GR32_System; 145 195 146 196 {$IFDEF OMIT_MMX} … … 173 223 end; 174 224 225 Af := @DivTable[FA]; 226 Ab := @DivTable[not FA]; 175 227 with BX do 176 228 begin 177 Af := @DivTable[FA];178 Ab := @DivTable[not FA];179 229 R := Af[FX.R] + Ab[R]; 180 230 G := Af[FX.G] + Ab[G]; 181 231 B := Af[FX.B] + Ab[B]; 232 A := $FF; 182 233 end; 183 234 Result := B; … … 201 252 end; 202 253 254 Af := @DivTable[FA]; 255 Ab := @DivTable[not FA]; 203 256 with BX do 204 257 begin 205 Af := @DivTable[FA];206 Ab := @DivTable[not FA];207 258 R := Af[FX.R] + Ab[R]; 208 259 G := Af[FX.G] + Ab[G]; 209 260 B := Af[FX.B] + Ab[B]; 261 A := $FF; 262 end; 263 end; 264 265 procedure BlendMems_Pas(F: TColor32; B: PColor32; Count: Integer); 266 begin 267 while Count > 0 do 268 begin 269 BlendMem(F, B^); 270 Inc(B); 271 Dec(Count); 210 272 end; 211 273 end; … … 233 295 end; 234 296 297 Ab := @DivTable[255 - M]; 235 298 with BX do 236 299 begin 237 Af := @DivTable[M];238 Ab := @DivTable[255 - M];239 300 R := Af[FX.R] + Ab[R]; 240 301 G := Af[FX.G] + Ab[G]; 241 302 B := Af[FX.B] + Ab[B]; 303 A := $FF; 242 304 end; 243 305 Result := B; … … 265 327 end; 266 328 329 Ab := @DivTable[255 - M]; 267 330 with BX do 268 331 begin 269 Af := @DivTable[M];270 Ab := @DivTable[255 - M];271 332 R := Af[FX.R] + Ab[R]; 272 333 G := Af[FX.G] + Ab[G]; 273 334 B := Af[FX.B] + Ab[B]; 335 A := $FF; 336 end; 337 end; 338 339 function BlendRegRGB_Pas(F, B, W: TColor32): TColor32; 340 var 341 FX: TColor32Entry absolute F; 342 BX: TColor32Entry absolute B; 343 WX: TColor32Entry absolute W; 344 RX: TColor32Entry absolute Result; 345 begin 346 RX.R := (FX.R - BX.R) * WX.B div 255 + BX.R; 347 RX.G := (FX.G - BX.G) * WX.G div 255 + BX.G; 348 RX.B := (FX.B - BX.B) * WX.R div 255 + BX.B; 349 end; 350 351 procedure BlendMemRGB_Pas(F: TColor32; var B: TColor32; W: TColor32); 352 var 353 FX: TColor32Entry absolute F; 354 BX: TColor32Entry absolute B; 355 WX: TColor32Entry absolute W; 356 begin 357 BX.R := (FX.R - BX.R) * WX.B div 255 + BX.R; 358 BX.G := (FX.G - BX.G) * WX.G div 255 + BX.G; 359 BX.B := (FX.B - BX.B) * WX.R div 255 + BX.B; 360 end; 361 362 procedure BlendLine1_Pas(Src: TColor32; Dst: PColor32; Count: Integer); 363 begin 364 while Count > 0 do 365 begin 366 BlendMem(Src, Dst^); 367 Inc(Dst); 368 Dec(Count); 274 369 end; 275 370 end; … … 315 410 end; 316 411 412 Af := @DivTable[W]; 413 Ab := @DivTable[255 - W]; 317 414 with Xe do 318 415 begin 319 Af := @DivTable[W];320 Ab := @DivTable[255 - W];321 416 R := Ab[Ye.R] + Af[R]; 322 417 G := Ab[Ye.G] + Af[G]; 323 418 B := Ab[Ye.B] + Af[B]; 419 A := Ab[Ye.A] + Af[A]; 324 420 end; 325 421 Result := X; … … 343 439 end; 344 440 441 Af := @DivTable[W]; 442 Ab := @DivTable[255 - W]; 345 443 with Xe do 346 444 begin 347 Af := @DivTable[W];348 Ab := @DivTable[255 - W];349 445 R := Ab[Ye.R] + Af[R]; 350 446 G := Ab[Ye.G] + Af[G]; 351 447 B := Ab[Ye.B] + Af[B]; 448 A := Ab[Ye.A] + Af[A]; 352 449 end; 353 450 Y := X; … … 367 464 function MergeReg_Pas(F, B: TColor32): TColor32; 368 465 var 369 Fa, Ba, Wa: TColor32;370 Fw, Bw: PByteArray;371 Fx: TColor32Entry absolute F;372 Bx: TColor32Entry absolute B;373 Rx: TColor32Entry absolute Result;374 begin 375 Fa := F shr 24;376 Ba := B shr 24;377 if Fa = $FF then378 Result := F379 else if Fa = $0 then380 Result := B381 else if Ba = $0 then382 Result := F383 else384 begin385 Rx.A := DivTable[Fa xor 255, Ba xor 255] xor 255;386 Wa := RcTable[Rx.A, Fa];387 Fw := @DivTable[Wa];388 Bw := @DivTable[Wa xor $ff];389 Rx.R := Fw[Fx.R] + Bw[Bx.R];390 Rx.G := Fw[Fx.G] + Bw[Bx.G];391 Rx.B := Fw[Fx.B] + Bw[Bx.B];392 end;466 Fa, Ba, Wa: TColor32; 467 Fw, Bw: PByteArray; 468 Fx: TColor32Entry absolute F; 469 Bx: TColor32Entry absolute B; 470 Rx: TColor32Entry absolute Result; 471 begin 472 Fa := F shr 24; 473 Ba := B shr 24; 474 if Fa = $FF then 475 Result := F 476 else if Fa = $0 then 477 Result := B 478 else if Ba = $0 then 479 Result := F 480 else 481 begin 482 Rx.A := DivTable[Fa xor 255, Ba xor 255] xor 255; 483 Wa := RcTable[Rx.A, Fa]; 484 Fw := @DivTable[Wa]; 485 Bw := @DivTable[Wa xor $FF]; 486 Rx.R := Fw[Fx.R] + Bw[Bx.R]; 487 Rx.G := Fw[Fx.G] + Bw[Bx.G]; 488 Rx.B := Fw[Fx.B] + Bw[Bx.B]; 489 end; 393 490 end; 394 491 … … 406 503 begin 407 504 B := MergeReg(DivTable[M, F shr 24] shl 24 or F and $00FFFFFF, B); 505 end; 506 507 procedure MergeLine1_Pas(Src: TColor32; Dst: PColor32; Count: Integer); 508 begin 509 while Count > 0 do 510 begin 511 Dst^ := MergeReg(Src, Dst^); 512 Inc(Dst); 513 Dec(Count); 514 end; 408 515 end; 409 516 … … 435 542 procedure EMMS_Pas; 436 543 begin 437 //Dummy544 // Dummy 438 545 end; 439 546 440 547 function LightenReg_Pas(C: TColor32; Amount: Integer): TColor32; 441 548 var 442 r, g, b , a: Integer;549 r, g, b: Integer; 443 550 CX: TColor32Entry absolute C; 444 551 RX: TColor32Entry absolute Result; 445 552 begin 446 a := CX.A;447 553 r := CX.R; 448 554 g := CX.G; … … 457 563 if b > 255 then b := 255 else if b < 0 then b := 0; 458 564 459 RX.A := a; 565 // preserve alpha 566 RX.A := CX.A; 460 567 RX.R := r; 461 568 RX.G := g; … … 467 574 function ColorAdd_Pas(C1, C2: TColor32): TColor32; 468 575 var 469 r1, g1, b1, a1: Integer; 470 r2, g2, b2, a2: Integer; 471 begin 472 a1 := C1 shr 24; 473 r1 := C1 and $00FF0000; 474 g1 := C1 and $0000FF00; 475 b1 := C1 and $000000FF; 476 477 a2 := C2 shr 24; 478 r2 := C2 and $00FF0000; 479 g2 := C2 and $0000FF00; 480 b2 := C2 and $000000FF; 481 482 a1 := a1 + a2; 483 r1 := r1 + r2; 484 g1 := g1 + g2; 485 b1 := b1 + b2; 486 487 if a1 > $FF then a1 := $FF; 488 if r1 > $FF0000 then r1 := $FF0000; 489 if g1 > $FF00 then g1 := $FF00; 490 if b1 > $FF then b1 := $FF; 491 492 Result := a1 shl 24 + r1 + g1 + b1; 576 Xe: TColor32Entry absolute C1; 577 Ye: TColor32Entry absolute C2; 578 R: TColor32Entry absolute Result; 579 begin 580 R.A := Clamp(Xe.A + Ye.A, 255); 581 R.R := Clamp(Xe.R + Ye.R, 255); 582 R.G := Clamp(Xe.G + Ye.G, 255); 583 R.B := Clamp(Xe.B + Ye.B, 255); 493 584 end; 494 585 495 586 function ColorSub_Pas(C1, C2: TColor32): TColor32; 496 587 var 497 r1, g1, b1, a1: Integer; 498 r2, g2, b2, a2: Integer; 499 begin 500 a1 := C1 shr 24; 501 r1 := C1 and $00FF0000; 502 g1 := C1 and $0000FF00; 503 b1 := C1 and $000000FF; 504 505 r1 := r1 shr 16; 506 g1 := g1 shr 8; 507 508 a2 := C2 shr 24; 509 r2 := C2 and $00FF0000; 510 g2 := C2 and $0000FF00; 511 b2 := C2 and $000000FF; 512 513 r2 := r2 shr 16; 514 g2 := g2 shr 8; 515 516 a1 := a1 - a2; 517 r1 := r1 - r2; 518 g1 := g1 - g2; 519 b1 := b1 - b2; 520 521 if a1 < 0 then a1 := 0; 522 if r1 < 0 then r1 := 0; 523 if g1 < 0 then g1 := 0; 524 if b1 < 0 then b1 := 0; 525 526 Result := a1 shl 24 + r1 shl 16 + g1 shl 8 + b1; 588 Xe: TColor32Entry absolute C1; 589 Ye: TColor32Entry absolute C2; 590 R: TColor32Entry absolute Result; 591 Temp: SmallInt; 592 begin 593 Temp := Xe.A - Ye.A; 594 if Temp < 0 then 595 R.A := 0 596 else 597 R.A := Temp; 598 Temp := Xe.R - Ye.R; 599 if Temp < 0 then 600 R.R := 0 601 else 602 R.R := Temp; 603 Temp := Xe.G - Ye.G; 604 if Temp < 0 then 605 R.G := 0 606 else 607 R.G := Temp; 608 Temp := Xe.B - Ye.B; 609 if Temp < 0 then 610 R.B := 0 611 else 612 R.B := Temp; 527 613 end; 528 614 529 615 function ColorDiv_Pas(C1, C2: TColor32): TColor32; 530 616 var 531 r1, g1, b1, a1: Integer; 532 r2, g2, b2, a2: Integer; 533 begin 534 a1 := C1 shr 24; 535 r1 := (C1 and $00FF0000) shr 16; 536 g1 := (C1 and $0000FF00) shr 8; 537 b1 := C1 and $000000FF; 538 539 a2 := C2 shr 24; 540 r2 := (C2 and $00FF0000) shr 16; 541 g2 := (C2 and $0000FF00) shr 8; 542 b2 := C2 and $000000FF; 543 544 if a1 = 0 then a1:=$FF 545 else a1 := (a2 shl 8) div a1; 546 if r1 = 0 then r1:=$FF 547 else r1 := (r2 shl 8) div r1; 548 if g1 = 0 then g1:=$FF 549 else g1 := (g2 shl 8) div g1; 550 if b1 = 0 then b1:=$FF 551 else b1 := (b2 shl 8) div b1; 552 553 if a1 > $FF then a1 := $FF; 554 if r1 > $FF then r1 := $FF; 555 if g1 > $FF then g1 := $FF; 556 if b1 > $FF then b1 := $FF; 557 558 Result := a1 shl 24 + r1 shl 16 + g1 shl 8 + b1; 617 C1e: TColor32Entry absolute C1; 618 C2e: TColor32Entry absolute C2; 619 Re: TColor32Entry absolute Result; 620 Temp: Word; 621 begin 622 if C1e.A = 0 then 623 Re.A := $FF 624 else 625 begin 626 Temp := (C2e.A shl 8) div C1e.A; 627 if Temp > $FF then 628 Re.A := $FF 629 else 630 Re.A := Temp; 631 end; 632 633 if C1e.R = 0 then 634 Re.R := $FF 635 else 636 begin 637 Temp := (C2e.R shl 8) div C1e.R; 638 if Temp > $FF then 639 Re.R := $FF 640 else 641 Re.R := Temp; 642 end; 643 644 if C1e.G = 0 then 645 Re.G := $FF 646 else 647 begin 648 Temp := (C2e.G shl 8) div C1e.G; 649 if Temp > $FF then 650 Re.G := $FF 651 else 652 Re.G := Temp; 653 end; 654 655 if C1e.B = 0 then 656 Re.B := $FF 657 else 658 begin 659 Temp := (C2e.B shl 8) div C1e.B; 660 if Temp > $FF then 661 Re.B := $FF 662 else 663 Re.B := Temp; 664 end; 559 665 end; 560 666 561 667 function ColorModulate_Pas(C1, C2: TColor32): TColor32; 562 668 var 563 REnt: TColor32Entry absolute Result;564 C2 Ent: TColor32Entry absolute C2;565 begin 566 Result := C1; 567 R Ent.A := (C2Ent.A * REnt.A) shr 8;568 R Ent.R := (C2Ent.R * REnt.R) shr 8;569 R Ent.G := (C2Ent.G * REnt.G) shr 8;570 R Ent.B := (C2Ent.B * REnt.B) shr 8;669 C1e: TColor32Entry absolute C2; 670 C2e: TColor32Entry absolute C2; 671 Re: TColor32Entry absolute Result; 672 begin 673 Re.A := (C2e.A * C1e.A + $80) shr 8; 674 Re.R := (C2e.R * C1e.R + $80) shr 8; 675 Re.G := (C2e.G * C1e.G + $80) shr 8; 676 Re.B := (C2e.B * C1e.B + $80) shr 8; 571 677 end; 572 678 … … 603 709 function ColorDifference_Pas(C1, C2: TColor32): TColor32; 604 710 var 605 r1, g1, b1, a1: TColor32; 606 r2, g2, b2, a2: TColor32; 607 begin 608 a1 := C1 shr 24; 609 r1 := C1 and $00FF0000; 610 g1 := C1 and $0000FF00; 611 b1 := C1 and $000000FF; 612 613 r1 := r1 shr 16; 614 g1 := g1 shr 8; 615 616 a2 := C2 shr 24; 617 r2 := C2 and $00FF0000; 618 g2 := C2 and $0000FF00; 619 b2 := C2 and $000000FF; 620 621 r2 := r2 shr 16; 622 g2 := g2 shr 8; 623 624 a1 := abs(a2 - a1); 625 r1 := abs(r2 - r1); 626 g1 := abs(g2 - g1); 627 b1 := abs(b2 - b1); 628 629 Result := a1 shl 24 + r1 shl 16 + g1 shl 8 + b1; 711 Xe: TColor32Entry absolute C1; 712 Ye: TColor32Entry absolute C2; 713 R: TColor32Entry absolute Result; 714 begin 715 R.A := Abs(Xe.A - Ye.A); 716 R.R := Abs(Xe.R - Ye.R); 717 R.G := Abs(Xe.G - Ye.G); 718 R.B := Abs(Xe.B - Ye.B); 630 719 end; 631 720 632 721 function ColorExclusion_Pas(C1, C2: TColor32): TColor32; 633 722 var 634 r1, g1, b1, a1: TColor32; 635 r2, g2, b2, a2: TColor32; 636 begin 637 a1 := C1 shr 24; 638 r1 := C1 and $00FF0000; 639 g1 := C1 and $0000FF00; 640 b1 := C1 and $000000FF; 641 642 r1 := r1 shr 16; 643 g1 := g1 shr 8; 644 645 a2 := C2 shr 24; 646 r2 := C2 and $00FF0000; 647 g2 := C2 and $0000FF00; 648 b2 := C2 and $000000FF; 649 650 r2 := r2 shr 16; 651 g2 := g2 shr 8; 652 653 a1 := a1 + a2 - (a1 * a2 shr 7); 654 r1 := r1 + r2 - (r1 * r2 shr 7); 655 g1 := g1 + g2 - (g1 * g2 shr 7); 656 b1 := b1 + b2 - (b1 * b2 shr 7); 657 658 Result := a1 shl 24 + r1 shl 16 + g1 shl 8 + b1; 723 Xe: TColor32Entry absolute C1; 724 Ye: TColor32Entry absolute C2; 725 R: TColor32Entry absolute Result; 726 begin 727 R.A := Xe.A + Ye.A - ((Xe.A * Ye.A) shl 7); 728 R.R := Xe.R + Ye.R - ((Xe.R * Ye.R) shr 7); 729 R.G := Xe.G + Ye.G - ((Xe.G * Ye.G) shr 7); 730 R.B := Xe.B + Ye.B - ((Xe.B * Ye.B) shr 7); 659 731 end; 660 732 … … 674 746 function ColorScale_Pas(C, W: TColor32): TColor32; 675 747 var 748 Ce: TColor32Entry absolute C; 749 var 676 750 r1, g1, b1, a1: Cardinal; 677 751 begin 678 a1 := C shr 24; 679 r1 := C and $00FF0000; 680 g1 := C and $0000FF00; 681 b1 := C and $000000FF; 682 683 r1 := r1 shr 16; 684 g1 := g1 shr 8; 685 686 a1 := a1 * W shr 8; 687 r1 := r1 * W shr 8; 688 g1 := g1 * W shr 8; 689 b1 := b1 * W shr 8; 752 a1 := Ce.A * W shr 8; 753 r1 := Ce.R * W shr 8; 754 g1 := Ce.G * W shr 8; 755 b1 := Ce.B * W shr 8; 690 756 691 757 if a1 > 255 then a1 := 255; … … 697 763 end; 698 764 765 function ColorScreen_Pas(B, S: TColor32): TColor32; 766 var 767 Be: TColor32Entry absolute B; 768 Se: TColor32Entry absolute S; 769 R: TColor32Entry absolute Result; 770 begin 771 R.A := Be.A + Se.A - (Be.A * Se.A) div 255; 772 R.R := Be.R + Se.R - (Be.R * Se.R) div 255; 773 R.G := Be.G + Se.G - (Be.G * Se.G) div 255; 774 R.B := Be.B + Se.B - (Be.B * Se.B) div 255; 775 end; 776 777 function ColorDodge_Pas(B, S: TColor32): TColor32; 778 779 function Dodge(B, S: Byte): Byte; 780 begin 781 if B = 0 then 782 Result := 0 783 else 784 if S = 255 then 785 Result := 255 786 else 787 Result := Clamp((255 * B) div (255 - S), 255); 788 end; 789 790 var 791 Be: TColor32Entry absolute B; 792 Se: TColor32Entry absolute S; 793 R: TColor32Entry absolute Result; 794 begin 795 R.A := Dodge(Be.A, Se.A); 796 R.R := Dodge(Be.R, Se.R); 797 R.G := Dodge(Be.G, Se.G); 798 R.B := Dodge(Be.B, Se.B); 799 end; 800 801 function ColorBurn_Pas(B, S: TColor32): TColor32; 802 803 function Burn(B, S: Byte): Byte; 804 begin 805 if B = 255 then 806 Result := 255 807 else 808 if S = 0 then 809 Result := 0 810 else 811 Result := 255 - Clamp(255 * (255 - B) div S, 255); 812 end; 813 814 var 815 Be: TColor32Entry absolute B; 816 Se: TColor32Entry absolute S; 817 R: TColor32Entry absolute Result; 818 begin 819 R.A := Burn(Be.A, Se.A); 820 R.R := Burn(Be.R, Se.R); 821 R.G := Burn(Be.G, Se.G); 822 R.B := Burn(Be.B, Se.B); 823 end; 824 825 826 { Blended color algebra } 827 828 function BlendColorAdd_Pas(C1, C2: TColor32): TColor32; 829 var 830 Xe: TColor32Entry absolute C1; 831 Ye: TColor32Entry absolute C2; 832 R: TColor32Entry absolute Result; 833 Af, Ab: PByteArray; 834 begin 835 Af := @DivTable[Xe.A]; 836 Ab := @DivTable[not Xe.A]; 837 R.A := Af[Clamp(Xe.A + Ye.A, 255)] + Ab[Ye.A]; 838 R.R := Af[Clamp(Xe.R + Ye.R, 255)] + Ab[Ye.R]; 839 R.G := Af[Clamp(Xe.G + Ye.G, 255)] + Ab[Ye.G]; 840 R.B := Af[Clamp(Xe.B + Ye.B, 255)] + Ab[Ye.B]; 841 end; 842 843 function BlendColorModulate_Pas(C1, C2: TColor32): TColor32; 844 var 845 C1e: TColor32Entry absolute C1; 846 C2e: TColor32Entry absolute C2; 847 R: TColor32Entry absolute Result; 848 Af, Ab: PByteArray; 849 begin 850 Af := @DivTable[C1e.A]; 851 Ab := @DivTable[not C1e.A]; 852 R.A := Af[(C2e.A * C1e.A + $80) shr 8] + Ab[C2e.A]; 853 R.R := Af[(C2e.R * C1e.R + $80) shr 8] + Ab[C2e.R]; 854 R.G := Af[(C2e.G * C1e.G + $80) shr 8] + Ab[C2e.G]; 855 R.B := Af[(C2e.B * C1e.B + $80) shr 8] + Ab[C2e.B]; 856 end; 857 699 858 {$IFNDEF PUREPASCAL} 700 701 { Assembler versions }702 703 const704 bias = $00800080;705 706 707 function BlendReg_ASM(F, B: TColor32): TColor32;708 asm709 // blend foreground color (F) to a background color (B),710 // using alpha channel value of F711 // Result Z = Fa * Frgb + (1 - Fa) * Brgb712 713 {$IFDEF TARGET_x86}714 // EAX <- F715 // EDX <- B716 717 // Test Fa = 255 ?718 CMP EAX,$FF000000 // Fa = 255 ? => Result = EAX719 JNC @2720 721 // Test Fa = 0 ?722 TEST EAX,$FF000000 // Fa = 0 ? => Result = EDX723 JZ @1724 725 // Get weight W = Fa * M726 MOV ECX,EAX // ECX <- Fa Fr Fg Fb727 SHR ECX,24 // ECX <- 00 00 00 Fa728 729 PUSH EBX730 731 // P = W * F732 MOV EBX,EAX // EBX <- Fa Fr Fg Fb733 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb734 AND EBX,$FF00FF00 // EBX <- Fa 00 Fg 00735 IMUL EAX,ECX // EAX <- Pr ** Pb **736 SHR EBX,8 // EBX <- 00 Fa 00 Fg737 IMUL EBX,ECX // EBX <- Pa ** Pg **738 ADD EAX,bias739 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 00740 SHR EAX,8 // EAX <- 00 Pr ** Pb741 ADD EBX,bias742 AND EBX,$FF00FF00 // EBX <- Pa 00 Pg 00743 OR EAX,EBX // EAX <- Pa Pr Pg Pb744 745 // W = 1 - W; Q = W * B746 XOR ECX,$000000FF // ECX <- 1 - ECX747 MOV EBX,EDX // EBX <- Ba Br Bg Bb748 AND EDX,$00FF00FF // EDX <- 00 Br 00 Bb749 AND EBX,$FF00FF00 // EBX <- Ba 00 Bg 00750 IMUL EDX,ECX // EDX <- Qr ** Qb **751 SHR EBX,8 // EBX <- 00 Ba 00 Bg752 IMUL EBX,ECX // EBX <- Qa ** Qg **753 ADD EDX,bias754 AND EDX,$FF00FF00 // EDX <- Qr 00 Qb 00755 SHR EDX,8 // EDX <- 00 Qr ** Qb756 ADD EBX,bias757 AND EBX,$FF00FF00 // EBX <- Qa 00 Qg 00758 OR EBX,EDX // EBX <- Qa Qr Qg Qb759 760 // Z = P + Q (assuming no overflow at each byte)761 ADD EAX,EBX // EAX <- Za Zr Zg Zb762 763 POP EBX764 {$IFDEF FPC}765 JMP @2766 {$ELSE}767 RET768 {$ENDIF}769 770 @1: MOV EAX,EDX771 @2:772 {$ENDIF}773 774 // EAX <- F775 // EDX <- B776 {$IFDEF TARGET_x64}777 MOV RAX, RCX778 779 // Test Fa = 255 ?780 CMP EAX,$FF000000 // Fa = 255 ? => Result = EAX781 JNC @2782 783 // Test Fa = 0 ?784 TEST EAX,$FF000000 // Fa = 0 ? => Result = EDX785 JZ @1786 787 // Get weight W = Fa * M788 MOV ECX,EAX // ECX <- Fa Fr Fg Fb789 SHR ECX,24 // ECX <- 00 00 00 Fa790 791 // P = W * F792 MOV R9D,EAX // R9D <- Fa Fr Fg Fb793 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb794 AND R9D,$FF00FF00 // R9D <- Fa 00 Fg 00795 IMUL EAX,ECX // EAX <- Pr ** Pb **796 SHR R9D,8 // R9D <- 00 Fa 00 Fg797 IMUL R9D,ECX // R9D <- Pa ** Pg **798 ADD EAX,bias799 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 00800 SHR EAX,8 // EAX <- 00 Pr ** Pb801 ADD R9D,bias802 AND R9D,$FF00FF00 // R9D <- Pa 00 Pg 00803 OR EAX,R9D // EAX <- Pa Pr Pg Pb804 805 // W = 1 - W; Q = W * B806 XOR ECX,$000000FF // ECX <- 1 - ECX807 MOV R9D,EDX // R9D <- Ba Br Bg Bb808 AND EDX,$00FF00FF // EDX <- 00 Br 00 Bb809 AND R9D,$FF00FF00 // R9D <- Ba 00 Bg 00810 IMUL EDX,ECX // EDX <- Qr ** Qb **811 SHR R9D,8 // R9D <- 00 Ba 00 Bg812 IMUL R9D,ECX // R9D <- Qa ** Qg **813 ADD EDX,bias814 AND EDX,$FF00FF00 // EDX <- Qr 00 Qb 00815 SHR EDX,8 // EDX <- 00 Qr ** Qb816 ADD R9D,bias817 AND R9D,$FF00FF00 // R9D <- Qa 00 Qg 00818 OR R9D,EDX // R9D <- Qa Qr Qg Qb819 820 // Z = P + Q (assuming no overflow at each byte)821 ADD EAX,R9D // EAX <- Za Zr Zg Zb822 {$IFDEF FPC}823 JMP @2824 {$ELSE}825 RET826 {$ENDIF}827 828 @1: MOV EAX,EDX829 @2:830 {$ENDIF}831 end;832 833 procedure BlendMem_ASM(F: TColor32; var B: TColor32);834 asm835 {$IFDEF TARGET_x86}836 // EAX <- F837 // [EDX] <- B838 839 // Test Fa = 0 ?840 TEST EAX,$FF000000 // Fa = 0 ? => do not write841 JZ @2842 843 // Get weight W = Fa * M844 MOV ECX,EAX // ECX <- Fa Fr Fg Fb845 SHR ECX,24 // ECX <- 00 00 00 Fa846 847 // Test Fa = 255 ?848 CMP ECX,$FF849 JZ @1850 851 PUSH EBX852 PUSH ESI853 854 // P = W * F855 MOV EBX,EAX // EBX <- Fa Fr Fg Fb856 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb857 AND EBX,$FF00FF00 // EBX <- Fa 00 Fg 00858 IMUL EAX,ECX // EAX <- Pr ** Pb **859 SHR EBX,8 // EBX <- 00 Fa 00 Fg860 IMUL EBX,ECX // EBX <- Pa ** Pg **861 ADD EAX,bias862 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 00863 SHR EAX,8 // EAX <- 00 Pr ** Pb864 ADD EBX,bias865 AND EBX,$FF00FF00 // EBX <- Pa 00 Pg 00866 OR EAX,EBX // EAX <- Pa Pr Pg Pb867 868 MOV ESI,[EDX]869 870 // W = 1 - W; Q = W * B871 XOR ECX,$000000FF // ECX <- 1 - ECX872 MOV EBX,ESI // EBX <- Ba Br Bg Bb873 AND ESI,$00FF00FF // ESI <- 00 Br 00 Bb874 AND EBX,$FF00FF00 // EBX <- Ba 00 Bg 00875 IMUL ESI,ECX // ESI <- Qr ** Qb **876 SHR EBX,8 // EBX <- 00 Ba 00 Bg877 IMUL EBX,ECX // EBX <- Qa ** Qg **878 ADD ESI,bias879 AND ESI,$FF00FF00 // ESI <- Qr 00 Qb 00880 SHR ESI,8 // ESI <- 00 Qr ** Qb881 ADD EBX,bias882 AND EBX,$FF00FF00 // EBX <- Qa 00 Qg 00883 OR EBX,ESI // EBX <- Qa Qr Qg Qb884 885 // Z = P + Q (assuming no overflow at each byte)886 ADD EAX,EBX // EAX <- Za Zr Zg Zb887 888 MOV [EDX],EAX889 POP ESI890 POP EBX891 {$IFDEF FPC}892 JMP @2893 {$ELSE}894 RET895 {$ENDIF}896 897 @1: MOV [EDX],EAX898 @2:899 {$ENDIF}900 901 {$IFDEF TARGET_x64}902 // ECX <- F903 // [RDX] <- B904 905 // Test Fa = 0 ?906 TEST ECX,$FF000000 // Fa = 0 ? => do not write907 JZ @2908 909 MOV EAX, ECX // EAX <- Fa Fr Fg Fb910 911 // Get weight W = Fa * M912 SHR ECX,24 // ECX <- 00 00 00 Fa913 914 // Test Fa = 255 ?915 CMP ECX,$FF916 JZ @1917 918 // P = W * F919 MOV R8D,EAX // R8D <- Fa Fr Fg Fb920 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb921 AND R8D,$FF00FF00 // R8D <- Fa 00 Fg 00922 IMUL EAX,ECX // EAX <- Pr ** Pb **923 SHR R8D,8 // R8D <- 00 Fa 00 Fg924 IMUL R8D,ECX // R8D <- Pa ** Pg **925 ADD EAX,bias926 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 00927 SHR EAX,8 // EAX <- 00 Pr ** Pb928 ADD R8D,bias929 AND R8D,$FF00FF00 // R8D <- Pa 00 Pg 00930 OR EAX,R8D // EAX <- Pa Pr Pg Pb931 932 MOV R9D,[RDX]933 934 // W = 1 - W; Q = W * B935 XOR ECX,$000000FF // ECX <- 1 - ECX936 MOV R8D,R9D // R8D <- Ba Br Bg Bb937 AND R9D,$00FF00FF // R9D <- 00 Br 00 Bb938 AND R8D,$FF00FF00 // R8D <- Ba 00 Bg 00939 IMUL R9D,ECX // R9D <- Qr ** Qb **940 SHR R8D,8 // R8D <- 00 Ba 00 Bg941 IMUL R8D,ECX // R8D <- Qa ** Qg **942 ADD R9D,bias943 AND R9D,$FF00FF00 // R9D <- Qr 00 Qb 00944 SHR R9D,8 // R9D <- 00 Qr ** Qb945 ADD R8D,bias946 AND R8D,$FF00FF00 // R8D <- Qa 00 Qg 00947 OR R8D,R9D // R8D <- Qa Qr Qg Qb948 949 // Z = P + Q (assuming no overflow at each byte)950 ADD EAX,R8D // EAX <- Za Zr Zg Zb951 952 MOV [RDX],EAX953 {$IFDEF FPC}954 JMP @2955 {$ELSE}956 RET957 {$ENDIF}958 959 @1: MOV [RDX],EAX960 @2:961 {$ENDIF}962 end;963 964 function BlendRegEx_ASM(F, B, M: TColor32): TColor32;965 asm966 // blend foreground color (F) to a background color (B),967 // using alpha channel value of F multiplied by master alpha (M)968 // no checking for M = $FF, in this case Graphics32 uses BlendReg969 // Result Z = Fa * M * Frgb + (1 - Fa * M) * Brgb970 // EAX <- F971 // EDX <- B972 // ECX <- M973 974 {$IFDEF TARGET_x86}975 976 // Check Fa > 0 ?977 TEST EAX,$FF000000 // Fa = 0? => Result := EDX978 JZ @2979 980 PUSH EBX981 982 // Get weight W = Fa * M983 MOV EBX,EAX // EBX <- Fa Fr Fg Fb984 INC ECX // 255:256 range bias985 SHR EBX,24 // EBX <- 00 00 00 Fa986 IMUL ECX,EBX // ECX <- 00 00 W **987 SHR ECX,8 // ECX <- 00 00 00 W988 JZ @1 // W = 0 ? => Result := EDX989 990 // P = W * F991 MOV EBX,EAX // EBX <- ** Fr Fg Fb992 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb993 AND EBX,$0000FF00 // EBX <- 00 00 Fg 00994 IMUL EAX,ECX // EAX <- Pr ** Pb **995 SHR EBX,8 // EBX <- 00 00 00 Fg996 IMUL EBX,ECX // EBX <- 00 00 Pg **997 ADD EAX,bias998 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 00999 SHR EAX,8 // EAX <- 00 Pr ** Pb1000 ADD EBX,bias1001 AND EBX,$0000FF00 // EBX <- 00 00 Pg 001002 OR EAX,EBX // EAX <- 00 Pr Pg Pb1003 1004 // W = 1 - W; Q = W * B1005 XOR ECX,$000000FF // ECX <- 1 - ECX1006 MOV EBX,EDX // EBX <- 00 Br Bg Bb1007 AND EDX,$00FF00FF // EDX <- 00 Br 00 Bb1008 AND EBX,$0000FF00 // EBX <- 00 00 Bg 001009 IMUL EDX,ECX // EDX <- Qr ** Qb **1010 SHR EBX,8 // EBX <- 00 00 00 Bg1011 IMUL EBX,ECX // EBX <- 00 00 Qg **1012 ADD EDX,bias1013 AND EDX,$FF00FF00 // EDX <- Qr 00 Qb 001014 SHR EDX,8 // EDX <- 00 Qr ** Qb1015 ADD EBX,bias1016 AND EBX,$0000FF00 // EBX <- 00 00 Qg 001017 OR EBX,EDX // EBX <- 00 Qr Qg Qb1018 1019 // Z = P + Q (assuming no overflow at each byte)1020 ADD EAX,EBX // EAX <- 00 Zr Zg Zb1021 1022 POP EBX1023 {$IFDEF FPC}1024 JMP @31025 {$ELSE}1026 RET1027 {$ENDIF}1028 1029 @1:1030 POP EBX1031 1032 @2: MOV EAX,EDX1033 @3:1034 {$ENDIF}1035 1036 {$IFDEF TARGET_x64}1037 MOV EAX,ECX // EAX <- Fa Fr Fg Fb1038 TEST EAX,$FF000000 // Fa = 0? => Result := EDX1039 JZ @11040 1041 // Get weight W = Fa * M1042 INC R8D // 255:256 range bias1043 SHR ECX,24 // ECX <- 00 00 00 Fa1044 IMUL R8D,ECX // R8D <- 00 00 W **1045 SHR R8D,8 // R8D <- 00 00 00 W1046 JZ @1 // W = 0 ? => Result := EDX1047 1048 // P = W * F1049 MOV ECX,EAX // ECX <- ** Fr Fg Fb1050 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb1051 AND ECX,$0000FF00 // ECX <- 00 00 Fg 001052 IMUL EAX,R8D // EAX <- Pr ** Pb **1053 SHR ECX,8 // ECX <- 00 00 00 Fg1054 IMUL ECX,R8D // ECX <- 00 00 Pg **1055 ADD EAX,bias1056 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 001057 SHR EAX,8 // EAX <- 00 Pr ** Pb1058 ADD ECX,bias1059 AND ECX,$0000FF00 // ECX <- 00 00 Pg 001060 OR EAX,ECX // EAX <- 00 Pr Pg Pb1061 1062 // W = 1 - W; Q = W * B1063 XOR R8D,$000000FF // R8D <- 1 - R8D1064 MOV ECX,EDX // ECX <- 00 Br Bg Bb1065 AND EDX,$00FF00FF // EDX <- 00 Br 00 Bb1066 AND ECX,$0000FF00 // ECX <- 00 00 Bg 001067 IMUL EDX,R8D // EDX <- Qr ** Qb **1068 SHR ECX,8 // ECX <- 00 00 00 Bg1069 IMUL ECX,R8D // ECX <- 00 00 Qg **1070 ADD EDX,bias1071 AND EDX,$FF00FF00 // EDX <- Qr 00 Qb 001072 SHR EDX,8 // EDX <- 00 Qr ** Qb1073 ADD ECX,bias1074 AND ECX,$0000FF00 // ECX <- 00 00 Qg 001075 OR ECX,EDX // ECX <- 00 Qr Qg Qb1076 1077 // Z = P + Q (assuming no overflow at each byte)1078 ADD EAX,ECX // EAX <- 00 Zr Zg Zb1079 1080 {$IFDEF FPC}1081 JMP @21082 {$ELSE}1083 RET1084 {$ENDIF}1085 1086 @1: MOV EAX,EDX1087 @2:1088 {$ENDIF}1089 end;1090 1091 procedure BlendMemEx_ASM(F: TColor32; var B: TColor32; M: TColor32);1092 asm1093 {$IFDEF TARGET_x86}1094 // EAX <- F1095 // [EDX] <- B1096 // ECX <- M1097 1098 // Check Fa > 0 ?1099 TEST EAX,$FF000000 // Fa = 0? => write nothing1100 JZ @21101 1102 PUSH EBX1103 1104 // Get weight W = Fa * M1105 MOV EBX,EAX // EBX <- Fa Fr Fg Fb1106 INC ECX // 255:256 range bias1107 SHR EBX,24 // EBX <- 00 00 00 Fa1108 IMUL ECX,EBX // ECX <- 00 00 W **1109 SHR ECX,8 // ECX <- 00 00 00 W1110 JZ @1 // W = 0 ? => write nothing1111 1112 PUSH ESI1113 1114 // P = W * F1115 MOV EBX,EAX // EBX <- ** Fr Fg Fb1116 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb1117 AND EBX,$0000FF00 // EBX <- 00 00 Fg 001118 IMUL EAX,ECX // EAX <- Pr ** Pb **1119 SHR EBX,8 // EBX <- 00 00 00 Fg1120 IMUL EBX,ECX // EBX <- 00 00 Pg **1121 ADD EAX,bias1122 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 001123 SHR EAX,8 // EAX <- 00 Pr ** Pb1124 ADD EBX,bias1125 AND EBX,$0000FF00 // EBX <- 00 00 Pg 001126 OR EAX,EBX // EAX <- 00 Pr Pg Pb1127 1128 // W = 1 - W; Q = W * B1129 MOV ESI,[EDX]1130 XOR ECX,$000000FF // ECX <- 1 - ECX1131 MOV EBX,ESI // EBX <- 00 Br Bg Bb1132 AND ESI,$00FF00FF // ESI <- 00 Br 00 Bb1133 AND EBX,$0000FF00 // EBX <- 00 00 Bg 001134 IMUL ESI,ECX // ESI <- Qr ** Qb **1135 SHR EBX,8 // EBX <- 00 00 00 Bg1136 IMUL EBX,ECX // EBX <- 00 00 Qg **1137 ADD ESI,bias1138 AND ESI,$FF00FF00 // ESI <- Qr 00 Qb 001139 SHR ESI,8 // ESI <- 00 Qr ** Qb1140 ADD EBX,bias1141 AND EBX,$0000FF00 // EBX <- 00 00 Qg 001142 OR EBX,ESI // EBX <- 00 Qr Qg Qb1143 1144 // Z = P + Q (assuming no overflow at each byte)1145 ADD EAX,EBX // EAX <- 00 Zr Zg Zb1146 1147 MOV [EDX],EAX1148 POP ESI1149 1150 @1: POP EBX1151 @2:1152 {$ENDIF}1153 1154 {$IFDEF TARGET_x64}1155 // ECX <- F1156 // [RDX] <- B1157 // R8 <- M1158 1159 // ECX <- F1160 // [EDX] <- B1161 // R8 <- M1162 1163 // Check Fa > 0 ?1164 TEST ECX,$FF000000 // Fa = 0? => write nothing1165 JZ @11166 1167 // Get weight W = Fa * M1168 MOV EAX,ECX // EAX <- Fa Fr Fg Fb1169 INC R8D // 255:256 range bias1170 SHR EAX,24 // EAX <- 00 00 00 Fa1171 IMUL R8D,EAX // R8D <- 00 00 W **1172 SHR R8D,8 // R8D <- 00 00 00 W1173 JZ @1 // W = 0 ? => write nothing1174 1175 // P = W * F1176 MOV EAX,ECX // EAX <- ** Fr Fg Fb1177 AND ECX,$00FF00FF // ECX <- 00 Fr 00 Fb1178 AND EAX,$0000FF00 // EAX <- 00 00 Fg 001179 IMUL ECX,R8D // ECX <- Pr ** Pb **1180 SHR EAX,8 // EAX <- 00 00 00 Fg1181 IMUL EAX,R8D // EAX <- 00 00 Pg **1182 ADD ECX,bias1183 AND ECX,$FF00FF00 // ECX <- Pr 00 Pb 001184 SHR ECX,8 // ECX <- 00 Pr ** Pb1185 ADD EAX,bias1186 AND EAX,$0000FF00 // EAX <- 00 00 Pg 001187 OR ECX,EAX // ECX <- 00 Pr Pg Pb1188 1189 // W = 1 - W; Q = W * B1190 MOV R9D,[RDX]1191 XOR R8D,$000000FF // R8D <- 1 - R81192 MOV EAX,R9D // EAX <- 00 Br Bg Bb1193 AND R9D,$00FF00FF // R9D <- 00 Br 00 Bb1194 AND EAX,$0000FF00 // EAX <- 00 00 Bg 001195 IMUL R9D,R8D // R9D <- Qr ** Qb **1196 SHR EAX,8 // EAX <- 00 00 00 Bg1197 IMUL EAX,R8D // EAX <- 00 00 Qg **1198 ADD R9D,bias1199 AND R9D,$FF00FF00 // R9D <- Qr 00 Qb 001200 SHR R9D,8 // R9D <- 00 Qr ** Qb1201 ADD EAX,bias1202 AND EAX,$0000FF00 // EAX <- 00 00 Qg 001203 OR EAX,R9D // EAX <- 00 Qr Qg Qb1204 1205 // Z = P + Q (assuming no overflow at each byte)1206 ADD ECX,EAX // ECX <- 00 Zr Zg Zb1207 1208 MOV [RDX],ECX1209 1210 @1:1211 {$ENDIF}1212 end;1213 1214 procedure BlendLine_ASM(Src, Dst: PColor32; Count: Integer);1215 asm1216 {$IFDEF TARGET_x86}1217 // EAX <- Src1218 // EDX <- Dst1219 // ECX <- Count1220 1221 // test the counter for zero or negativity1222 TEST ECX,ECX1223 JS @41224 1225 PUSH EBX1226 PUSH ESI1227 PUSH EDI1228 1229 MOV ESI,EAX // ESI <- Src1230 MOV EDI,EDX // EDI <- Dst1231 1232 // loop start1233 @1: MOV EAX,[ESI]1234 TEST EAX,$FF0000001235 JZ @3 // complete transparency, proceed to next point1236 1237 PUSH ECX // store counter1238 1239 // Get weight W = Fa * M1240 MOV ECX,EAX // ECX <- Fa Fr Fg Fb1241 SHR ECX,24 // ECX <- 00 00 00 Fa1242 1243 // Test Fa = 255 ?1244 CMP ECX,$FF1245 JZ @21246 1247 // P = W * F1248 MOV EBX,EAX // EBX <- Fa Fr Fg Fb1249 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb1250 AND EBX,$FF00FF00 // EBX <- Fa 00 Fg 001251 IMUL EAX,ECX // EAX <- Pr ** Pb **1252 SHR EBX,8 // EBX <- 00 Fa 00 Fg1253 IMUL EBX,ECX // EBX <- Pa ** Pg **1254 ADD EAX,bias1255 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 001256 SHR EAX,8 // EAX <- 00 Pr ** Pb1257 ADD EBX,bias1258 AND EBX,$FF00FF00 // EBX <- Pa 00 Pg 001259 OR EAX,EBX // EAX <- Pa Pr Pg Pb1260 1261 // W = 1 - W; Q = W * B1262 MOV EDX,[EDI]1263 XOR ECX,$000000FF // ECX <- 1 - ECX1264 MOV EBX,EDX // EBX <- Ba Br Bg Bb1265 AND EDX,$00FF00FF // ESI <- 00 Br 00 Bb1266 AND EBX,$FF00FF00 // EBX <- Ba 00 Bg 001267 IMUL EDX,ECX // ESI <- Qr ** Qb **1268 SHR EBX,8 // EBX <- 00 Ba 00 Bg1269 IMUL EBX,ECX // EBX <- Qa ** Qg **1270 ADD EDX,bias1271 AND EDX,$FF00FF00 // ESI <- Qr 00 Qb 001272 SHR EDX,8 // ESI <- 00 Qr ** Qb1273 ADD EBX,bias1274 AND EBX,$FF00FF00 // EBX <- Qa 00 Qg 001275 OR EBX,EDX // EBX <- Qa Qr Qg Qb1276 1277 // Z = P + Q (assuming no overflow at each byte)1278 ADD EAX,EBX // EAX <- Za Zr Zg Zb1279 @2:1280 MOV [EDI],EAX1281 1282 POP ECX // restore counter1283 1284 @3:1285 ADD ESI,41286 ADD EDI,41287 1288 // loop end1289 DEC ECX1290 JNZ @11291 1292 POP EDI1293 POP ESI1294 POP EBX1295 1296 @4:1297 {$ENDIF}1298 1299 {$IFDEF TARGET_x64}1300 // RCX <- Src1301 // RDX <- Dst1302 // R8 <- Count1303 1304 // test the counter for zero or negativity1305 TEST R8D,R8D1306 JS @41307 1308 MOV R10,RCX // R10 <- Src1309 MOV R11,RDX // R11 <- Dst1310 MOV ECX,R8D // RCX <- Count1311 1312 // loop start1313 @1:1314 MOV EAX,[R10]1315 TEST EAX,$FF0000001316 JZ @3 // complete transparency, proceed to next point1317 1318 // Get weight W = Fa * M1319 MOV R9D,EAX // R9D <- Fa Fr Fg Fb1320 SHR R9D,24 // R9D <- 00 00 00 Fa1321 1322 // Test Fa = 255 ?1323 CMP R9D,$FF1324 JZ @21325 1326 // P = W * F1327 MOV R8D,EAX // R8D <- Fa Fr Fg Fb1328 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb1329 AND R8D,$FF00FF00 // R8D <- Fa 00 Fg 001330 IMUL EAX,R9D // EAX <- Pr ** Pb **1331 SHR R8D,8 // R8D <- 00 Fa 00 Fg1332 IMUL R8D,R9D // R8D <- Pa ** Pg **1333 ADD EAX,bias1334 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 001335 SHR EAX,8 // EAX <- 00 Pr ** Pb1336 ADD R8D,bias1337 AND R8D,$FF00FF00 // R8D <- Pa 00 Pg 001338 OR EAX,R8D // EAX <- Pa Pr Pg Pb1339 1340 // W = 1 - W; Q = W * B1341 MOV EDX,[R11]1342 XOR R9D,$000000FF // R9D <- 1 - R9D1343 MOV R8D,EDX // R8D <- Ba Br Bg Bb1344 AND EDX,$00FF00FF // ESI <- 00 Br 00 Bb1345 AND R8D,$FF00FF00 // R8D <- Ba 00 Bg 001346 IMUL EDX,R9D // ESI <- Qr ** Qb **1347 SHR R8D,8 // R8D <- 00 Ba 00 Bg1348 IMUL R8D,R9D // R8D <- Qa ** Qg **1349 ADD EDX,bias1350 AND EDX,$FF00FF00 // ESI <- Qr 00 Qb 001351 SHR EDX,8 // ESI <- 00 Qr ** Qb1352 ADD R8D,bias1353 AND R8D,$FF00FF00 // R8D <- Qa 00 Qg 001354 OR R8D,EDX // R8D <- Qa Qr Qg Qb1355 1356 // Z = P + Q (assuming no overflow at each byte)1357 ADD EAX,R8D // EAX <- Za Zr Zg Zb1358 @2:1359 MOV [R11],EAX1360 1361 @3:1362 ADD R10,41363 ADD R11,41364 1365 // loop end1366 DEC ECX1367 JNZ @11368 1369 @4:1370 {$ENDIF}1371 end;1372 1373 {$IFDEF TARGET_x86}1374 1375 function MergeReg_ASM(F, B: TColor32): TColor32;1376 asm1377 // EAX <- F1378 // EDX <- B1379 1380 // if F.A = 0 then1381 TEST EAX,$FF0000001382 JZ @exit01383 1384 // else if B.A = 255 then1385 CMP EDX,$FF0000001386 JNC @blend1387 1388 // else if F.A = 255 then1389 CMP EAX,$FF0000001390 JNC @Exit1391 1392 // else if B.A = 0 then1393 TEST EDX,$FF0000001394 JZ @Exit1395 1396 @4:1397 PUSH EBX1398 PUSH ESI1399 PUSH EDI1400 ADD ESP,-$0C1401 MOV [ESP+$04],EDX1402 MOV [ESP],EAX1403 1404 // AH <- F.A1405 // DL, CL <- B.A1406 SHR EAX,161407 AND EAX,$0000FF001408 SHR EDX,241409 MOV CL,DL1410 NOP1411 NOP1412 NOP1413 1414 // EDI <- PF1415 // EDX <- PB1416 // ESI <- PR1417 1418 // PF := @DivTable[F.A];1419 LEA EDI,[EAX+DivTable]1420 // PB := @DivTable[B.A];1421 SHL EDX,$081422 LEA EDX,[EDX+DivTable]1423 // Result.A := B.A + F.A - PB[F.A];1424 SHR EAX,81425 //ADD CL,al1426 ADD ECX,EAX1427 //SUB CL,[EDX+EAX]1428 SUB ECX,[EDX+EAX]1429 MOV [ESP+$0B],CL1430 // PR := @RcTable[Result.A];1431 SHL ECX,$081432 AND ECX,$0000FFFF1433 LEA ESI,[ECX+RcTable]1434 1435 { Red component }1436 1437 // Result.R := PB[B.R];1438 XOR EAX,EAX1439 MOV AL,[ESP+$06]1440 MOV CL,[EDX+EAX]1441 MOV [ESP+$0a],CL1442 // X := F.R - Result.R;1443 MOV AL,[ESP+$02]1444 XOR EBX,EBX1445 MOV BL,CL1446 SUB EAX,EBX1447 // if X >= 0 then1448 JL @51449 // Result.R := PR[PF[X] + Result.R]1450 MOVZX EAX,BYTE PTR[EDI+EAX]1451 AND ECX,$000000FF1452 ADD EAX,ECX1453 MOV AL,[ESI+EAX]1454 MOV [ESP+$0a],al1455 JMP @61456 @5:1457 // Result.R := PR[Result.R - PF[-X]];1458 NEG EAX1459 MOVZX EAX,BYTE PTR[EDI+EAX]1460 XOR ECX,ECX1461 MOV CL,[ESP+$0A]1462 SUB ECX,EAX1463 MOV AL,[ESI+ECX]1464 MOV [ESP+$0A],al1465 1466 1467 { Green component }1468 1469 @6:1470 // Result.G := PB[B.G];1471 XOR EAX,EAX1472 MOV AL,[ESP+$05]1473 MOV CL,[EDX+EAX]1474 MOV [ESP+$09],CL1475 // X := F.G - Result.G;1476 MOV AL,[ESP+$01]1477 XOR EBX,EBX1478 MOV BL,CL1479 SUB EAX,EBX1480 // if X >= 0 then1481 JL @71482 // Result.G := PR[PF[X] + Result.G]1483 MOVZX EAX,BYTE PTR[EDI+EAX]1484 AND ECX,$000000FF1485 ADD EAX,ECX1486 MOV AL,[ESI+EAX]1487 MOV [ESP+$09],AL1488 JMP @81489 @7:1490 // Result.G := PR[Result.G - PF[-X]];1491 NEG EAX1492 MOVZX EAX,BYTE PTR[EDI+EAX]1493 XOR ECX,ECX1494 MOV CL,[ESP+$09]1495 SUB ECX,EAX1496 MOV AL,[ESI+ECX]1497 MOV [ESP+$09],AL1498 1499 1500 { Blue component }1501 @8:1502 // Result.B := PB[B.B];1503 XOR EAX,EAX1504 MOV AL,[ESP+$04]1505 MOV CL,[EDX+EAX]1506 MOV [ESP+$08],CL1507 // X := F.B - Result.B;1508 MOV AL,[ESP]1509 XOR EDX,EDX1510 MOV DL,CL1511 SUB EAX,EDX1512 // if X >= 0 then1513 JL @91514 // Result.B := PR[PF[X] + Result.B]1515 MOVZX EAX,BYTE PTR[EDI+EAX]1516 XOR EDX,EDX1517 MOV DL,CL1518 ADD EAX,EDX1519 MOV AL,[ESI+EAX]1520 MOV [ESP+$08],al1521 JMP @101522 @9:1523 // Result.B := PR[Result.B - PF[-X]];1524 NEG EAX1525 MOVZX EAX,BYTE PTR[EDI+EAX]1526 XOR EDX,EDX1527 MOV DL,CL1528 SUB EDX,EAX1529 MOV AL,[ESI+EDX]1530 MOV [ESP+$08],AL1531 1532 @10:1533 // EAX <- Result1534 MOV EAX,[ESP+$08]1535 1536 // end;1537 ADD ESP,$0C1538 POP EDI1539 POP ESI1540 POP EBX1541 {$IFDEF FPC}1542 JMP @Exit1543 {$ELSE}1544 RET1545 {$ENDIF}1546 @blend:1547 CALL DWORD PTR [BlendReg]1548 OR EAX,$FF0000001549 {$IFDEF FPC}1550 JMP @Exit1551 {$ELSE}1552 RET1553 {$ENDIF}1554 @exit0:1555 MOV EAX,EDX1556 @Exit:1557 end;1558 1559 {$ENDIF}1560 1561 function CombineReg_ASM(X, Y, W: TColor32): TColor32;1562 asm1563 // combine RGBA channels of colors X and Y with the weight of X given in W1564 // Result Z = W * X + (1 - W) * Y (all channels are combined, including alpha)1565 {$IFDEF TARGET_x86}1566 // EAX <- X1567 // EDX <- Y1568 // ECX <- W1569 1570 // W = 0 or $FF?1571 JCXZ @1 // CX = 0 ? => Result := EDX1572 CMP ECX,$FF // CX = $FF ? => Result := EDX1573 JE @21574 1575 PUSH EBX1576 1577 // P = W * X1578 MOV EBX,EAX // EBX <- Xa Xr Xg Xb1579 AND EAX,$00FF00FF // EAX <- 00 Xr 00 Xb1580 AND EBX,$FF00FF00 // EBX <- Xa 00 Xg 001581 IMUL EAX,ECX // EAX <- Pr ** Pb **1582 SHR EBX,8 // EBX <- 00 Xa 00 Xg1583 IMUL EBX,ECX // EBX <- Pa ** Pg **1584 ADD EAX,bias1585 AND EAX,$FF00FF00 // EAX <- Pa 00 Pg 001586 SHR EAX,8 // EAX <- 00 Pr 00 Pb1587 ADD EBX,bias1588 AND EBX,$FF00FF00 // EBX <- Pa 00 Pg 001589 OR EAX,EBX // EAX <- Pa Pr Pg Pb1590 1591 // W = 1 - W; Q = W * Y1592 XOR ECX,$000000FF // ECX <- 1 - ECX1593 MOV EBX,EDX // EBX <- Ya Yr Yg Yb1594 AND EDX,$00FF00FF // EDX <- 00 Yr 00 Yb1595 AND EBX,$FF00FF00 // EBX <- Ya 00 Yg 001596 IMUL EDX,ECX // EDX <- Qr ** Qb **1597 SHR EBX,8 // EBX <- 00 Ya 00 Yg1598 IMUL EBX,ECX // EBX <- Qa ** Qg **1599 ADD EDX,bias1600 AND EDX,$FF00FF00 // EDX <- Qr 00 Qb 001601 SHR EDX,8 // EDX <- 00 Qr ** Qb1602 ADD EBX,bias1603 AND EBX,$FF00FF00 // EBX <- Qa 00 Qg 001604 OR EBX,EDX // EBX <- Qa Qr Qg Qb1605 1606 // Z = P + Q (assuming no overflow at each byte)1607 ADD EAX,EBX // EAX <- Za Zr Zg Zb1608 1609 POP EBX1610 {$IFDEF FPC}1611 JMP @21612 {$ELSE}1613 RET1614 {$ENDIF}1615 1616 @1: MOV EAX,EDX1617 @2:1618 {$ENDIF}1619 1620 {$IFDEF TARGET_x64}1621 // ECX <- X1622 // EDX <- Y1623 // R8D <- W1624 1625 // W = 0 or $FF?1626 TEST R8D,R8D1627 JZ @1 // W = 0 ? => Result := EDX1628 MOV EAX,ECX // EAX <- Xa Xr Xg Xb1629 CMP R8B,$FF // W = $FF ? => Result := EDX1630 JE @21631 1632 // P = W * X1633 AND EAX,$00FF00FF // EAX <- 00 Xr 00 Xb1634 AND ECX,$FF00FF00 // ECX <- Xa 00 Xg 001635 IMUL EAX,R8D // EAX <- Pr ** Pb **1636 SHR ECX,8 // ECX <- 00 Xa 00 Xg1637 IMUL ECX,R8D // ECX <- Pa ** Pg **1638 ADD EAX,bias1639 AND EAX,$FF00FF00 // EAX <- Pa 00 Pg 001640 SHR EAX,8 // EAX <- 00 Pr 00 Pb1641 ADD ECX,bias1642 AND ECX,$FF00FF00 // ECX <- Pa 00 Pg 001643 OR EAX,ECX // EAX <- Pa Pr Pg Pb1644 1645 // W = 1 - W; Q = W * Y1646 XOR R8D,$000000FF // R8D <- 1 - R8D1647 MOV ECX,EDX // ECX <- Ya Yr Yg Yb1648 AND EDX,$00FF00FF // EDX <- 00 Yr 00 Yb1649 AND ECX,$FF00FF00 // ECX <- Ya 00 Yg 001650 IMUL EDX,R8D // EDX <- Qr ** Qb **1651 SHR ECX,8 // ECX <- 00 Ya 00 Yg1652 IMUL ECX,R8D // ECX <- Qa ** Qg **1653 ADD EDX,bias1654 AND EDX,$FF00FF00 // EDX <- Qr 00 Qb 001655 SHR EDX,8 // EDX <- 00 Qr ** Qb1656 ADD ECX,bias1657 AND ECX,$FF00FF00 // ECX <- Qa 00 Qg 001658 OR ECX,EDX // ECX <- Qa Qr Qg Qb1659 1660 // Z = P + Q (assuming no overflow at each byte)1661 ADD EAX,ECX // EAX <- Za Zr Zg Zb1662 1663 {$IFDEF FPC}1664 JMP @21665 {$ELSE}1666 RET1667 {$ENDIF}1668 1669 @1: MOV EAX,EDX1670 @2:1671 {$ENDIF}1672 end;1673 1674 procedure CombineMem_ASM(X: TColor32; var Y: TColor32; W: TColor32);1675 asm1676 {$IFDEF TARGET_x86}1677 // EAX <- F1678 // [EDX] <- B1679 // ECX <- W1680 1681 // Check W1682 JCXZ @1 // W = 0 ? => write nothing1683 CMP ECX,$FF // W = 255? => write F1684 {$IFDEF FPC}1685 DB $74,$76 //Prob with FPC 2.2.2 and below1686 {$ELSE}1687 JZ @21688 {$ENDIF}1689 1690 1691 PUSH EBX1692 PUSH ESI1693 1694 // P = W * F1695 MOV EBX,EAX // EBX <- ** Fr Fg Fb1696 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb1697 AND EBX,$FF00FF00 // EBX <- Fa 00 Fg 001698 IMUL EAX,ECX // EAX <- Pr ** Pb **1699 SHR EBX,8 // EBX <- 00 Fa 00 Fg1700 IMUL EBX,ECX // EBX <- 00 00 Pg **1701 ADD EAX,bias1702 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 001703 SHR EAX,8 // EAX <- 00 Pr 00 Pb1704 ADD EBX,bias1705 AND EBX,$FF00FF00 // EBX <- Pa 00 Pg 001706 OR EAX,EBX // EAX <- 00 Pr Pg Pb1707 1708 // W = 1 - W; Q = W * B1709 MOV ESI,[EDX]1710 XOR ECX,$000000FF // ECX <- 1 - ECX1711 MOV EBX,ESI // EBX <- Ba Br Bg Bb1712 AND ESI,$00FF00FF // ESI <- 00 Br 00 Bb1713 AND EBX,$FF00FF00 // EBX <- Ba 00 Bg 001714 IMUL ESI,ECX // ESI <- Qr ** Qb **1715 SHR EBX,8 // EBX <- 00 Ba 00 Bg1716 IMUL EBX,ECX // EBX <- Qa 00 Qg **1717 ADD ESI,bias1718 AND ESI,$FF00FF00 // ESI <- Qr 00 Qb 001719 SHR ESI,8 // ESI <- 00 Qr ** Qb1720 ADD EBX,bias1721 AND EBX,$FF00FF00 // EBX <- Qa 00 Qg 001722 OR EBX,ESI // EBX <- 00 Qr Qg Qb1723 1724 // Z = P + Q (assuming no overflow at each byte)1725 ADD EAX,EBX // EAX <- 00 Zr Zg Zb1726 1727 MOV [EDX],EAX1728 1729 POP ESI1730 POP EBX1731 {$IFDEF FPC}1732 @1: JMP @31733 {$ELSE}1734 @1: RET1735 {$ENDIF}1736 1737 @2: MOV [EDX],EAX1738 @3:1739 {$ENDIF}1740 1741 {$IFDEF TARGET_x64}1742 // ECX <- F1743 // [RDX] <- B1744 // R8 <- W1745 1746 // Check W1747 TEST R8D,R8D // Set flags for R81748 JZ @2 // W = 0 ? => Result := EDX1749 MOV EAX,ECX // EAX <- ** Fr Fg Fb1750 CMP R8B,$FF // W = 255? => write F1751 JZ @11752 1753 // P = W * F1754 AND EAX,$00FF00FF // EAX <- 00 Fr 00 Fb1755 AND ECX,$FF00FF00 // ECX <- Fa 00 Fg 001756 IMUL EAX,R8D // EAX <- Pr ** Pb **1757 SHR ECX,8 // ECX <- 00 Fa 00 Fg1758 IMUL ECX,R8D // ECX <- 00 00 Pg **1759 ADD EAX,bias1760 AND EAX,$FF00FF00 // EAX <- Pr 00 Pb 001761 SHR EAX,8 // EAX <- 00 Pr 00 Pb1762 ADD ECX,bias1763 AND ECX,$FF00FF00 // ECX <- Pa 00 Pg 001764 OR EAX,ECX // EAX <- 00 Pr Pg Pb1765 1766 // W = 1 - W; Q = W * B1767 MOV R9D,[RDX]1768 XOR R8D,$000000FF // R8D <- 1 - R8D1769 MOV ECX,R9D // ECX <- Ba Br Bg Bb1770 AND R9D,$00FF00FF // R9D <- 00 Br 00 Bb1771 AND ECX,$FF00FF00 // ECX <- Ba 00 Bg 001772 IMUL R9D,R8D // R9D <- Qr ** Qb **1773 SHR ECX,8 // ECX <- 00 Ba 00 Bg1774 IMUL ECX,R8D // ECX <- Qa 00 Qg **1775 ADD R9D,bias1776 AND R9D,$FF00FF00 // R9D <- Qr 00 Qb 001777 SHR R9D,8 // R9D <- 00 Qr ** Qb1778 ADD ECX,bias1779 AND ECX,$FF00FF00 // ECX <- Qa 00 Qg 001780 OR ECX,R9D // ECX <- 00 Qr Qg Qb1781 1782 // Z = P + Q (assuming no overflow at each byte)1783 ADD EAX,ECX // EAX <- 00 Zr Zg Zb1784 1785 @1: MOV [RDX],EAX1786 @2:1787 1788 {$ENDIF}1789 end;1790 1791 procedure EMMS_ASM;1792 asm1793 end;1794 859 1795 860 procedure GenAlphaTable; … … 1830 895 FreeMem(AlphaTable); 1831 896 end; 1832 1833 {$IFNDEF OMIT_MMX}1834 1835 { MMX versions }1836 1837 function BlendReg_MMX(F, B: TColor32): TColor32;1838 asm1839 // blend foreground color (F) to a background color (B),1840 // using alpha channel value of F1841 {$IFDEF TARGET_x86}1842 // EAX <- F1843 // EDX <- B1844 // Result := Fa * (Frgb - Brgb) + Brgb1845 MOVD MM0,EAX1846 PXOR MM3,MM31847 MOVD MM2,EDX1848 PUNPCKLBW MM0,MM31849 MOV ECX,bias_ptr1850 PUNPCKLBW MM2,MM31851 MOVQ MM1,MM01852 PUNPCKHWD MM1,MM11853 PSUBW MM0,MM21854 PUNPCKHDQ MM1,MM11855 PSLLW MM2,81856 PMULLW MM0,MM11857 PADDW MM2,[ECX]1858 PADDW MM2,MM01859 PSRLW MM2,81860 PACKUSWB MM2,MM31861 MOVD EAX,MM21862 {$ENDIF}1863 1864 {$IFDEF TARGET_x64}1865 // ECX <- F1866 // EDX <- B1867 // Result := Fa * (Frgb - Brgb) + Brgb1868 MOVD MM0,ECX1869 PXOR MM3,MM31870 MOVD MM2,EDX1871 PUNPCKLBW MM0,MM31872 MOV RAX,bias_ptr1873 PUNPCKLBW MM2,MM31874 MOVQ MM1,MM01875 PUNPCKHWD MM1,MM11876 PSUBW MM0,MM21877 PUNPCKHDQ MM1,MM11878 PSLLW MM2,81879 PMULLW MM0,MM11880 PADDW MM2,[RAX]1881 PADDW MM2,MM01882 PSRLW MM2,81883 PACKUSWB MM2,MM31884 MOVD EAX,MM21885 {$ENDIF}1886 end;1887 1888 {$IFDEF TARGET_x86}1889 1890 procedure BlendMem_MMX(F: TColor32; var B: TColor32);1891 asm1892 // EAX - Color X1893 // [EDX] - Color Y1894 // Result := W * (X - Y) + Y1895 1896 TEST EAX,$FF0000001897 JZ @11898 CMP EAX,$FF0000001899 JNC @21900 1901 PXOR MM3,MM31902 MOVD MM0,EAX1903 MOVD MM2,[EDX]1904 PUNPCKLBW MM0,MM31905 MOV ECX,bias_ptr1906 PUNPCKLBW MM2,MM31907 MOVQ MM1,MM01908 PUNPCKHWD MM1,MM11909 PSUBW MM0,MM21910 PUNPCKHDQ MM1,MM11911 PSLLW MM2,81912 PMULLW MM0,MM11913 PADDW MM2,[ECX]1914 PADDW MM2,MM01915 PSRLW MM2,81916 PACKUSWB MM2,MM31917 MOVD [EDX],MM21918 1919 {$IFDEF FPC}1920 @1: JMP @31921 {$ELSE}1922 @1: RET1923 {$ENDIF}1924 1925 @2: MOV [EDX],EAX1926 @3:1927 end;1928 1929 function BlendRegEx_MMX(F, B, M: TColor32): TColor32;1930 asm1931 // blend foreground color (F) to a background color (B),1932 // using alpha channel value of F1933 // EAX <- F1934 // EDX <- B1935 // ECX <- M1936 // Result := M * Fa * (Frgb - Brgb) + Brgb1937 PUSH EBX1938 MOV EBX,EAX1939 SHR EBX,241940 INC ECX // 255:256 range bias1941 IMUL ECX,EBX1942 SHR ECX,81943 JZ @11944 1945 PXOR MM0,MM01946 MOVD MM1,EAX1947 SHL ECX,41948 MOVD MM2,EDX1949 PUNPCKLBW MM1,MM01950 PUNPCKLBW MM2,MM01951 ADD ECX,alpha_ptr1952 PSUBW MM1,MM21953 PMULLW MM1,[ECX]1954 PSLLW MM2,81955 MOV ECX,bias_ptr1956 PADDW MM2,[ECX]1957 PADDW MM1,MM21958 PSRLW MM1,81959 PACKUSWB MM1,MM01960 MOVD EAX,MM11961 1962 POP EBX1963 {$IFDEF FPC}1964 JMP @21965 {$ELSE}1966 RET1967 {$ENDIF}1968 1969 @1: MOV EAX,EDX1970 POP EBX1971 @2:1972 end;1973 1974 {$ENDIF}1975 1976 procedure BlendMemEx_MMX(F: TColor32; var B:TColor32; M: TColor32);1977 asm1978 {$IFDEF TARGET_x86}1979 // blend foreground color (F) to a background color (B),1980 // using alpha channel value of F1981 // EAX <- F1982 // [EDX] <- B1983 // ECX <- M1984 // Result := M * Fa * (Frgb - Brgb) + Brgb1985 TEST EAX,$FF0000001986 JZ @21987 1988 PUSH EBX1989 MOV EBX,EAX1990 SHR EBX,241991 INC ECX // 255:256 range bias1992 IMUL ECX,EBX1993 SHR ECX,81994 JZ @11995 1996 PXOR MM0,MM01997 MOVD MM1,EAX1998 SHL ECX,41999 MOVD MM2,[EDX]2000 PUNPCKLBW MM1,MM02001 PUNPCKLBW MM2,MM02002 ADD ECX,alpha_ptr2003 PSUBW MM1,MM22004 PMULLW MM1,[ECX]2005 PSLLW MM2,82006 MOV ECX,bias_ptr2007 PADDW MM2,[ECX]2008 PADDW MM1,MM22009 PSRLW MM1,82010 PACKUSWB MM1,MM02011 MOVD [EDX],MM12012 2013 @1: POP EBX2014 2015 @2:2016 {$ENDIF}2017 2018 {$IFDEF TARGET_x64}2019 // blend foreground color (F) to a background color (B),2020 // using alpha channel value of F2021 // ECX <- F2022 // [EDX] <- B2023 // R8 <- M2024 // Result := M * Fa * (Frgb - Brgb) + Brgb2025 TEST ECX,$FF0000002026 JZ @12027 2028 MOV EAX,ECX2029 SHR EAX,242030 INC R8D // 255:256 range bias2031 IMUL R8D,EAX2032 SHR R8D,82033 JZ @12034 2035 PXOR MM0,MM02036 MOVD MM1,ECX2037 SHL R8D,42038 MOVD MM2,[RDX]2039 PUNPCKLBW MM1,MM02040 PUNPCKLBW MM2,MM02041 ADD R8,alpha_ptr2042 PSUBW MM1,MM22043 PMULLW MM1,[R8]2044 PSLLW MM2,82045 MOV RAX,bias_ptr2046 PADDW MM2,[RAX]2047 PADDW MM1,MM22048 PSRLW MM1,82049 PACKUSWB MM1,MM02050 MOVD [RDX],MM12051 2052 @1:2053 {$ENDIF}2054 end;2055 2056 {$IFDEF TARGET_x86}2057 procedure BlendLine_MMX(Src, Dst: PColor32; Count: Integer);2058 asm2059 // EAX <- Src2060 // EDX <- Dst2061 // ECX <- Count2062 2063 // test the counter for zero or negativity2064 TEST ECX,ECX2065 JS @42066 2067 PUSH ESI2068 PUSH EDI2069 2070 MOV ESI,EAX // ESI <- Src2071 MOV EDI,EDX // EDI <- Dst2072 2073 // loop start2074 @1: MOV EAX,[ESI]2075 TEST EAX,$FF0000002076 JZ @3 // complete transparency, proceed to next point2077 CMP EAX,$FF0000002078 JNC @2 // opaque pixel, copy without blending2079 2080 // blend2081 MOVD MM0,EAX // MM0 <- 00 00 00 00 Fa Fr Fg Fb2082 PXOR MM3,MM3 // MM3 <- 00 00 00 00 00 00 00 002083 MOVD MM2,[EDI] // MM2 <- 00 00 00 00 Ba Br Bg Bb2084 PUNPCKLBW MM0,MM3 // MM0 <- 00 Fa 00 Fr 00 Fg 00 Fb2085 MOV EAX,bias_ptr2086 PUNPCKLBW MM2,MM3 // MM2 <- 00 Ba 00 Br 00 Bg 00 Bb2087 MOVQ MM1,MM0 // MM1 <- 00 Fa 00 Fr 00 Fg 00 Fb2088 PUNPCKHWD MM1,MM1 // MM1 <- 00 Fa 00 Fa 00 ** 00 **2089 PSUBW MM0,MM2 // MM0 <- 00 Da 00 Dr 00 Dg 00 Db2090 PUNPCKHDQ MM1,MM1 // MM1 <- 00 Fa 00 Fa 00 Fa 00 Fa2091 PSLLW MM2,8 // MM2 <- Ba 00 Br 00 Bg 00 Bb 002092 PMULLW MM0,MM1 // MM2 <- Pa ** Pr ** Pg ** Pb **2093 PADDW MM2,[EAX] // add bias2094 PADDW MM2,MM0 // MM2 <- Qa ** Qr ** Qg ** Qb **2095 PSRLW MM2,8 // MM2 <- 00 Qa 00 Qr 00 Qg 00 Qb2096 PACKUSWB MM2,MM3 // MM2 <- 00 00 00 00 Qa Qr Qg Qb2097 MOVD EAX,MM22098 2099 @2: MOV [EDI],EAX2100 2101 @3: ADD ESI,42102 ADD EDI,42103 2104 // loop end2105 DEC ECX2106 JNZ @12107 2108 POP EDI2109 POP ESI2110 2111 @4:2112 end;2113 2114 procedure BlendLineEx_MMX(Src, Dst: PColor32; Count: Integer; M: TColor32);2115 asm2116 // EAX <- Src2117 // EDX <- Dst2118 // ECX <- Count2119 2120 // test the counter for zero or negativity2121 TEST ECX,ECX2122 JS @42123 2124 PUSH ESI2125 PUSH EDI2126 PUSH EBX2127 2128 MOV ESI,EAX // ESI <- Src2129 MOV EDI,EDX // EDI <- Dst2130 MOV EDX,M // EDX <- Master Alpha2131 2132 // loop start2133 @1: MOV EAX,[ESI]2134 TEST EAX,$FF0000002135 JZ @3 // complete transparency, proceed to next point2136 MOV EBX,EAX2137 SHR EBX,242138 INC EBX // 255:256 range bias2139 IMUL EBX,EDX2140 SHR EBX,82141 JZ @3 // complete transparency, proceed to next point2142 2143 // blend2144 PXOR MM0,MM02145 MOVD MM1,EAX2146 SHL EBX,42147 MOVD MM2,[EDI]2148 PUNPCKLBW MM1,MM02149 PUNPCKLBW MM2,MM02150 ADD EBX,alpha_ptr2151 PSUBW MM1,MM22152 PMULLW MM1,[EBX]2153 PSLLW MM2,82154 MOV EBX,bias_ptr2155 PADDW MM2,[EBX]2156 PADDW MM1,MM22157 PSRLW MM1,82158 PACKUSWB MM1,MM02159 MOVD EAX,MM12160 2161 @2: MOV [EDI],EAX2162 2163 @3: ADD ESI,42164 ADD EDI,42165 2166 // loop end2167 DEC ECX2168 JNZ @12169 2170 POP EBX2171 POP EDI2172 POP ESI2173 @4:2174 end;2175 2176 {$ENDIF}2177 2178 function CombineReg_MMX(X, Y, W: TColor32): TColor32;2179 asm2180 {$IFDEF TARGET_X86}2181 // EAX - Color X2182 // EDX - Color Y2183 // ECX - Weight of X [0..255]2184 // Result := W * (X - Y) + Y2185 2186 MOVD MM1,EAX2187 PXOR MM0,MM02188 SHL ECX,42189 2190 MOVD MM2,EDX2191 PUNPCKLBW MM1,MM02192 PUNPCKLBW MM2,MM02193 2194 ADD ECX,alpha_ptr2195 2196 PSUBW MM1,MM22197 PMULLW MM1,[ECX]2198 PSLLW MM2,82199 2200 MOV ECX,bias_ptr2201 2202 PADDW MM2,[ECX]2203 PADDW MM1,MM22204 PSRLW MM1,82205 PACKUSWB MM1,MM02206 MOVD EAX,MM12207 {$ENDIF}2208 2209 {$IFDEF TARGET_X64}2210 // ECX - Color X2211 // EDX - Color Y2212 // R8 - Weight of X [0..255]2213 // Result := W * (X - Y) + Y2214 2215 MOVD MM1,ECX2216 PXOR MM0,MM02217 SHL R8D,42218 2219 MOVD MM2,EDX2220 PUNPCKLBW MM1,MM02221 PUNPCKLBW MM2,MM02222 2223 ADD R8,alpha_ptr2224 2225 PSUBW MM1,MM22226 PMULLW MM1,[R8]2227 PSLLW MM2,82228 2229 MOV RAX,bias_ptr2230 2231 PADDW MM2,[RAX]2232 PADDW MM1,MM22233 PSRLW MM1,82234 PACKUSWB MM1,MM02235 MOVD EAX,MM12236 {$ENDIF}2237 end;2238 2239 procedure CombineMem_MMX(F: TColor32; var B: TColor32; W: TColor32);2240 asm2241 {$IFDEF TARGET_X86}2242 // EAX - Color X2243 // [EDX] - Color Y2244 // ECX - Weight of X [0..255]2245 // Result := W * (X - Y) + Y2246 2247 JCXZ @12248 CMP ECX,$FF2249 JZ @22250 2251 MOVD MM1,EAX2252 PXOR MM0,MM02253 2254 SHL ECX,42255 2256 MOVD MM2,[EDX]2257 PUNPCKLBW MM1,MM02258 PUNPCKLBW MM2,MM02259 2260 ADD ECX,alpha_ptr2261 2262 PSUBW MM1,MM22263 PMULLW MM1,[ECX]2264 PSLLW MM2,82265 2266 MOV ECX,bias_ptr2267 2268 PADDW MM2,[ECX]2269 PADDW MM1,MM22270 PSRLW MM1,82271 PACKUSWB MM1,MM02272 MOVD [EDX],MM12273 2274 {$IFDEF FPC}2275 @1: JMP @32276 {$ELSE}2277 @1: RET2278 {$ENDIF}2279 2280 @2: MOV [EDX],EAX2281 @3:2282 {$ENDIF}2283 2284 {$IFDEF TARGET_x64}2285 // ECX - Color X2286 // [RDX] - Color Y2287 // R8 - Weight of X [0..255]2288 // Result := W * (X - Y) + Y2289 2290 TEST R8D,R8D // Set flags for R82291 JZ @1 // W = 0 ? => Result := EDX2292 CMP R8D,$FF2293 JZ @22294 2295 MOVD MM1,ECX2296 PXOR MM0,MM02297 2298 SHL R8D,42299 2300 MOVD MM2,[RDX]2301 PUNPCKLBW MM1,MM02302 PUNPCKLBW MM2,MM02303 2304 ADD R8,alpha_ptr2305 2306 PSUBW MM1,MM22307 PMULLW MM1,[R8]2308 PSLLW MM2,82309 2310 MOV RAX,bias_ptr2311 2312 PADDW MM2,[RAX]2313 PADDW MM1,MM22314 PSRLW MM1,82315 PACKUSWB MM1,MM02316 MOVD [RDX],MM12317 2318 {$IFDEF FPC}2319 @1: JMP @32320 {$ELSE}2321 @1: RET2322 {$ENDIF}2323 2324 @2: MOV [RDX],RCX2325 @3:2326 {$ENDIF}2327 end;2328 2329 {$IFDEF TARGET_x86}2330 2331 procedure CombineLine_MMX(Src, Dst: PColor32; Count: Integer; W: TColor32);2332 asm2333 // EAX <- Src2334 // EDX <- Dst2335 // ECX <- Count2336 2337 // Result := W * (X - Y) + Y2338 2339 TEST ECX,ECX2340 JS @32341 2342 PUSH EBX2343 MOV EBX,W2344 2345 TEST EBX,EBX2346 JZ @2 // weight is zero2347 2348 CMP EBX,$FF2349 JZ @4 // weight = 255 => copy src to dst2350 2351 SHL EBX,42352 ADD EBX,alpha_ptr2353 MOVQ MM3,[EBX]2354 MOV EBX,bias_ptr2355 MOVQ MM4,[EBX]2356 2357 // loop start2358 @1: MOVD MM1,[EAX]2359 PXOR MM0,MM02360 MOVD MM2,[EDX]2361 PUNPCKLBW MM1,MM02362 PUNPCKLBW MM2,MM02363 2364 PSUBW MM1,MM22365 PMULLW MM1,MM32366 PSLLW MM2,82367 2368 PADDW MM2,MM42369 PADDW MM1,MM22370 PSRLW MM1,82371 PACKUSWB MM1,MM02372 MOVD [EDX],MM12373 2374 ADD EAX,42375 ADD EDX,42376 2377 DEC ECX2378 JNZ @12379 @2: POP EBX2380 POP EBP2381 @3: RET $00042382 2383 @4: CALL GR32_LowLevel.MoveLongword2384 POP EBX2385 end;2386 2387 {$ENDIF}2388 2389 procedure EMMS_MMX;2390 asm2391 EMMS2392 end;2393 2394 function LightenReg_MMX(C: TColor32; Amount: Integer): TColor32;2395 asm2396 {$IFDEF TARGET_X86}2397 MOVD MM0,EAX2398 TEST EDX,EDX2399 JL @12400 IMUL EDX,$0101012401 MOVD MM1,EDX2402 PADDUSB MM0,MM12403 MOVD EAX,MM02404 RET2405 @1: NEG EDX2406 IMUL EDX,$0101012407 MOVD MM1,EDX2408 PSUBUSB MM0,MM12409 MOVD EAX,MM02410 {$ENDIF}2411 2412 {$IFDEF TARGET_X64}2413 MOVD MM0,ECX2414 TEST EDX,EDX2415 JL @12416 IMUL EDX,$0101012417 MOVD MM1,EDX2418 PADDUSB MM0,MM12419 MOVD EAX,MM02420 RET2421 @1: NEG EDX2422 IMUL EDX,$0101012423 MOVD MM1,EDX2424 PSUBUSB MM0,MM12425 MOVD EAX,MM02426 {$ENDIF}2427 end;2428 2429 { MMX Color algebra versions }2430 2431 function ColorAdd_MMX(C1, C2: TColor32): TColor32;2432 asm2433 {$IFDEF TARGET_X86}2434 MOVD MM0,EAX2435 MOVD MM1,EDX2436 PADDUSB MM0,MM12437 MOVD EAX,MM02438 {$ENDIF}2439 2440 {$IFDEF TARGET_X64}2441 MOVD MM0,ECX2442 MOVD MM1,EDX2443 PADDUSB MM0,MM12444 MOVD EAX,MM02445 {$ENDIF}2446 end;2447 2448 function ColorSub_MMX(C1, C2: TColor32): TColor32;2449 asm2450 {$IFDEF TARGET_X86}2451 MOVD MM0,EAX2452 MOVD MM1,EDX2453 PSUBUSB MM0,MM12454 MOVD EAX,MM02455 {$ENDIF}2456 2457 {$IFDEF TARGET_X64}2458 MOVD MM0,ECX2459 MOVD MM1,EDX2460 PSUBUSB MM0,MM12461 MOVD EAX,MM02462 {$ENDIF}2463 end;2464 2465 function ColorModulate_MMX(C1, C2: TColor32): TColor32;2466 asm2467 {$IFDEF TARGET_X86}2468 PXOR MM2,MM22469 MOVD MM0,EAX2470 PUNPCKLBW MM0,MM22471 MOVD MM1,EDX2472 PUNPCKLBW MM1,MM22473 PMULLW MM0,MM12474 PSRLW MM0,82475 PACKUSWB MM0,MM22476 MOVD EAX,MM02477 {$ENDIF}2478 2479 {$IFDEF TARGET_X64}2480 PXOR MM2,MM22481 MOVD MM0,ECX2482 PUNPCKLBW MM0,MM22483 MOVD MM1,EDX2484 PUNPCKLBW MM1,MM22485 PMULLW MM0,MM12486 PSRLW MM0,82487 PACKUSWB MM0,MM22488 MOVD EAX,MM02489 {$ENDIF}2490 end;2491 2492 function ColorMax_EMMX(C1, C2: TColor32): TColor32;2493 asm2494 {$IFDEF TARGET_X86}2495 MOVD MM0,EAX2496 MOVD MM1,EDX2497 PMAXUB MM0,MM12498 MOVD EAX,MM02499 {$ENDIF}2500 2501 {$IFDEF TARGET_X64}2502 MOVD MM0,ECX2503 MOVD MM1,EDX2504 PMAXUB MM0,MM12505 MOVD EAX,MM02506 {$ENDIF}2507 end;2508 2509 function ColorMin_EMMX(C1, C2: TColor32): TColor32;2510 asm2511 {$IFDEF TARGET_X86}2512 MOVD MM0,EAX2513 MOVD MM1,EDX2514 PMINUB MM0,MM12515 MOVD EAX,MM02516 {$ENDIF}2517 2518 {$IFDEF TARGET_X64}2519 MOVD MM0,ECX2520 MOVD MM1,EDX2521 PMINUB MM0,MM12522 MOVD EAX,MM02523 {$ENDIF}2524 end;2525 2526 function ColorDifference_MMX(C1, C2: TColor32): TColor32;2527 asm2528 {$IFDEF TARGET_X86}2529 MOVD MM0,EAX2530 MOVD MM1,EDX2531 MOVQ MM2,MM02532 PSUBUSB MM0,MM12533 PSUBUSB MM1,MM22534 POR MM0,MM12535 MOVD EAX,MM02536 {$ENDIF}2537 2538 {$IFDEF TARGET_X64}2539 MOVD MM0,ECX2540 MOVD MM1,EDX2541 MOVQ MM2,MM02542 PSUBUSB MM0,MM12543 PSUBUSB MM1,MM22544 POR MM0,MM12545 MOVD EAX,MM02546 {$ENDIF}2547 end;2548 2549 function ColorExclusion_MMX(C1, C2: TColor32): TColor32;2550 asm2551 {$IFDEF TARGET_X86}2552 PXOR MM2,MM22553 MOVD MM0,EAX2554 PUNPCKLBW MM0,MM22555 MOVD MM1,EDX2556 PUNPCKLBW MM1,MM22557 MOVQ MM3,MM02558 PADDW MM0,MM12559 PMULLW MM1,MM32560 PSRLW MM1,72561 PSUBUSW MM0,MM12562 PACKUSWB MM0,MM22563 MOVD EAX,MM02564 {$ENDIF}2565 2566 {$IFDEF TARGET_X64}2567 PXOR MM2,MM22568 MOVD MM0,ECX2569 PUNPCKLBW MM0,MM22570 MOVD MM1,EDX2571 PUNPCKLBW MM1,MM22572 MOVQ MM3,MM02573 PADDW MM0,MM12574 PMULLW MM1,MM32575 PSRLW MM1,72576 PSUBUSW MM0,MM12577 PACKUSWB MM0,MM22578 MOVD EAX,MM02579 {$ENDIF}2580 end;2581 2582 function ColorScale_MMX(C, W: TColor32): TColor32;2583 asm2584 {$IFDEF TARGET_X86}2585 PXOR MM2,MM22586 SHL EDX,42587 MOVD MM0,EAX2588 PUNPCKLBW MM0,MM22589 ADD EDX,alpha_ptr2590 PMULLW MM0,[EDX]2591 PSRLW MM0,82592 PACKUSWB MM0,MM22593 MOVD EAX,MM02594 {$ENDIF}2595 2596 {$IFDEF TARGET_X64}2597 PXOR MM2,MM22598 SHL RDX,42599 MOVD MM0,ECX2600 PUNPCKLBW MM0,MM22601 ADD RDX,alpha_ptr2602 PMULLW MM0,[RDX]2603 PSRLW MM0,82604 PACKUSWB MM0,MM22605 MOVD EAX,MM02606 {$ENDIF}2607 end;2608 {$ENDIF}2609 2610 2611 { SSE2 versions }2612 2613 {$IFNDEF OMIT_SSE2}2614 2615 function BlendReg_SSE2(F, B: TColor32): TColor32;2616 asm2617 // blend foreground color (F) to a background color (B),2618 // using alpha channel value of F2619 // EAX <- F2620 // EDX <- B2621 // Result := Fa * (Frgb - Brgb) + Brgb2622 2623 {$IFDEF TARGET_x86}2624 MOVD XMM0,EAX2625 PXOR XMM3,XMM32626 MOVD XMM2,EDX2627 PUNPCKLBW XMM0,XMM32628 MOV ECX,bias_ptr2629 PUNPCKLBW XMM2,XMM32630 MOVQ XMM1,XMM02631 PSHUFLW XMM1,XMM1, $FF2632 PSUBW XMM0,XMM22633 PSLLW XMM2,82634 PMULLW XMM0,XMM12635 PADDW XMM2,[ECX]2636 PADDW XMM2,XMM02637 PSRLW XMM2,82638 PACKUSWB XMM2,XMM32639 MOVD EAX,XMM22640 {$ENDIF}2641 2642 {$IFDEF TARGET_x64}2643 MOVD XMM0,ECX2644 PXOR XMM3,XMM32645 MOVD XMM2,EDX2646 PUNPCKLBW XMM0,XMM32647 MOV RAX,bias_ptr2648 PUNPCKLBW XMM2,XMM32649 MOVQ XMM1,XMM02650 PSHUFLW XMM1,XMM1, $FF2651 PSUBW XMM0,XMM22652 PSLLW XMM2,82653 PMULLW XMM0,XMM12654 PADDW XMM2,[RAX]2655 PADDW XMM2,XMM02656 PSRLW XMM2,82657 PACKUSWB XMM2,XMM32658 MOVD EAX,XMM22659 {$ENDIF}2660 end;2661 2662 procedure BlendMem_SSE2(F: TColor32; var B: TColor32);2663 asm2664 {$IFDEF TARGET_x86}2665 // EAX - Color X2666 // [EDX] - Color Y2667 // Result := W * (X - Y) + Y2668 2669 TEST EAX,$FF0000002670 JZ @12671 CMP EAX,$FF0000002672 JNC @22673 2674 PXOR XMM3,XMM32675 MOVD XMM0,EAX2676 MOVD XMM2,[EDX]2677 PUNPCKLBW XMM0,XMM32678 MOV ECX,bias_ptr2679 PUNPCKLBW XMM2,XMM32680 MOVQ XMM1,XMM02681 PSHUFLW XMM1,XMM1, $FF2682 PSUBW XMM0,XMM22683 PSLLW XMM2,82684 PMULLW XMM0,XMM12685 PADDW XMM2,[ECX]2686 PADDW XMM2,XMM02687 PSRLW XMM2,82688 PACKUSWB XMM2,XMM32689 MOVD [EDX],XMM22690 2691 {$IFDEF FPC}2692 @1: JMP @32693 {$ELSE}2694 @1: RET2695 {$ENDIF}2696 2697 @2: MOV [EDX], EAX2698 @3:2699 {$ENDIF}2700 2701 {$IFDEF TARGET_x64}2702 // ECX - Color X2703 // [EDX] - Color Y2704 // Result := W * (X - Y) + Y2705 2706 TEST ECX,$FF0000002707 JZ @12708 CMP ECX,$FF0000002709 JNC @22710 2711 PXOR XMM3,XMM32712 MOVD XMM0,ECX2713 MOVD XMM2,[RDX]2714 PUNPCKLBW XMM0,XMM32715 MOV RAX,bias_ptr2716 PUNPCKLBW XMM2,XMM32717 MOVQ XMM1,XMM02718 PSHUFLW XMM1,XMM1, $FF2719 PSUBW XMM0,XMM22720 PSLLW XMM2,82721 PMULLW XMM0,XMM12722 PADDW XMM2,[RAX]2723 PADDW XMM2,XMM02724 PSRLW XMM2,82725 PACKUSWB XMM2,XMM32726 MOVD [RDX],XMM22727 2728 {$IFDEF FPC}2729 @1: JMP @32730 {$ELSE}2731 @1: RET2732 {$ENDIF}2733 2734 @2: MOV [RDX], ECX2735 @3:2736 {$ENDIF}2737 end;2738 2739 function BlendRegEx_SSE2(F, B, M: TColor32): TColor32;2740 asm2741 // blend foreground color (F) to a background color (B),2742 // using alpha channel value of F2743 // Result := M * Fa * (Frgb - Brgb) + Brgb2744 2745 {$IFDEF TARGET_x86}2746 // EAX <- F2747 // EDX <- B2748 // ECX <- M2749 PUSH EBX2750 MOV EBX,EAX2751 SHR EBX,242752 INC ECX // 255:256 range bias2753 IMUL ECX,EBX2754 SHR ECX,82755 JZ @12756 2757 PXOR XMM0,XMM02758 MOVD XMM1,EAX2759 SHL ECX,42760 MOVD XMM2,EDX2761 PUNPCKLBW XMM1,XMM02762 PUNPCKLBW XMM2,XMM02763 ADD ECX,alpha_ptr2764 PSUBW XMM1,XMM22765 PMULLW XMM1,[ECX]2766 PSLLW XMM2,82767 MOV ECX,bias_ptr2768 PADDW XMM2,[ECX]2769 PADDW XMM1,XMM22770 PSRLW XMM1,82771 PACKUSWB XMM1,XMM02772 MOVD EAX,XMM12773 2774 POP EBX2775 {$IFDEF FPC}2776 JMP @22777 {$ELSE}2778 RET2779 {$ENDIF}2780 2781 @1: MOV EAX,EDX2782 POP EBX2783 @2:2784 {$ENDIF}2785 2786 {$IFDEF TARGET_x64}2787 // ECX <- F2788 // EDX <- B2789 // R8D <- M2790 2791 MOV EAX,ECX2792 SHR EAX,242793 INC R8D // 255:256 range bias2794 IMUL R8D,EAX2795 SHR R8D,82796 JZ @12797 2798 PXOR XMM0,XMM02799 MOVD XMM1,ECX2800 SHL R8D,42801 MOVD XMM2,EDX2802 PUNPCKLBW XMM1,XMM02803 PUNPCKLBW XMM2,XMM02804 ADD R8,alpha_ptr2805 PSUBW XMM1,XMM22806 PMULLW XMM1,[R8]2807 PSLLW XMM2,82808 MOV R8,bias_ptr2809 PADDW XMM2,[R8]2810 PADDW XMM1,XMM22811 PSRLW XMM1,82812 PACKUSWB XMM1,XMM02813 MOVD EAX,XMM12814 {$IFDEF FPC}2815 JMP @22816 {$ELSE}2817 RET2818 {$ENDIF}2819 2820 @1: MOV EAX,EDX2821 @2:2822 {$ENDIF}2823 end;2824 2825 procedure BlendMemEx_SSE2(F: TColor32; var B:TColor32; M: TColor32);2826 asm2827 {$IFDEF TARGET_x86}2828 // blend foreground color (F) to a background color (B),2829 // using alpha channel value of F2830 // EAX <- F2831 // [EDX] <- B2832 // ECX <- M2833 // Result := M * Fa * (Frgb - Brgb) + Brgb2834 TEST EAX,$FF0000002835 JZ @22836 2837 PUSH EBX2838 MOV EBX,EAX2839 SHR EBX,242840 INC ECX // 255:256 range bias2841 IMUL ECX,EBX2842 SHR ECX,82843 JZ @12844 2845 PXOR XMM0,XMM02846 MOVD XMM1,EAX2847 SHL ECX,42848 MOVD XMM2,[EDX]2849 PUNPCKLBW XMM1,XMM02850 PUNPCKLBW XMM2,XMM02851 ADD ECX,alpha_ptr2852 PSUBW XMM1,XMM22853 PMULLW XMM1,[ECX]2854 PSLLW XMM2,82855 MOV ECX,bias_ptr2856 PADDW XMM2,[ECX]2857 PADDW XMM1,XMM22858 PSRLW XMM1,82859 PACKUSWB XMM1,XMM02860 MOVD [EDX],XMM12861 2862 @1:2863 POP EBX2864 2865 @2:2866 {$ENDIF}2867 2868 {$IFDEF TARGET_x64}2869 // blend foreground color (F) to a background color (B),2870 // using alpha channel value of F2871 // RCX <- F2872 // [RDX] <- B2873 // R8 <- M2874 // Result := M * Fa * (Frgb - Brgb) + Brgb2875 2876 TEST ECX, $FF0000002877 JZ @12878 2879 MOV R9D,ECX2880 SHR R9D,242881 INC R8D // 255:256 range bias2882 IMUL R8D,R9D2883 SHR R8D,82884 JZ @12885 2886 PXOR XMM0,XMM02887 MOVD XMM1,ECX2888 SHL R8D,42889 MOVD XMM2,[RDX]2890 PUNPCKLBW XMM1,XMM02891 PUNPCKLBW XMM2,XMM02892 ADD R8,alpha_ptr2893 PSUBW XMM1,XMM22894 PMULLW XMM1,[R8]2895 PSLLW XMM2,82896 MOV R8,bias_ptr2897 PADDW XMM2,[R8]2898 PADDW XMM1,XMM22899 PSRLW XMM1,82900 PACKUSWB XMM1,XMM02901 MOVD DWORD PTR [RDX],XMM12902 @1:2903 {$ENDIF}2904 end;2905 2906 procedure BlendLine_SSE2(Src, Dst: PColor32; Count: Integer);2907 asm2908 {$IFDEF TARGET_X86}2909 // EAX <- Src2910 // EDX <- Dst2911 // ECX <- Count2912 2913 TEST ECX,ECX2914 JZ @42915 2916 PUSH EBX2917 2918 MOV EBX,EAX2919 2920 @1: MOV EAX,[EBX]2921 TEST EAX,$FF0000002922 JZ @32923 CMP EAX,$FF0000002924 JNC @22925 2926 MOVD XMM0,EAX2927 PXOR XMM3,XMM32928 MOVD XMM2,[EDX]2929 PUNPCKLBW XMM0,XMM32930 MOV EAX,bias_ptr2931 PUNPCKLBW XMM2,XMM32932 MOVQ XMM1,XMM02933 PUNPCKLBW XMM1,XMM32934 PUNPCKHWD XMM1,XMM12935 PSUBW XMM0,XMM22936 PUNPCKHDQ XMM1,XMM12937 PSLLW XMM2,82938 PMULLW XMM0,XMM12939 PADDW XMM2,[EAX]2940 PADDW XMM2,XMM02941 PSRLW XMM2,82942 PACKUSWB XMM2,XMM32943 MOVD EAX, XMM22944 2945 @2: MOV [EDX],EAX2946 2947 @3: ADD EBX,42948 ADD EDX,42949 2950 DEC ECX2951 JNZ @12952 2953 POP EBX2954 2955 @4:2956 {$ENDIF}2957 2958 {$IFDEF TARGET_X64}2959 // ECX <- Src2960 // EDX <- Dst2961 // R8D <- Count2962 2963 TEST R8D,R8D2964 JZ @42965 2966 @1: MOV EAX,[RCX]2967 TEST EAX,$FF0000002968 JZ @32969 CMP EAX,$FF0000002970 JNC @22971 2972 MOVD XMM0,EAX2973 PXOR XMM3,XMM32974 MOVD XMM2,[RDX]2975 PUNPCKLBW XMM0,XMM32976 MOV RAX,bias_ptr2977 PUNPCKLBW XMM2,XMM32978 MOVQ XMM1,XMM02979 PUNPCKLBW XMM1,XMM32980 PUNPCKHWD XMM1,XMM12981 PSUBW XMM0,XMM22982 PUNPCKHDQ XMM1,XMM12983 PSLLW XMM2,82984 PMULLW XMM0,XMM12985 PADDW XMM2,[RAX]2986 PADDW XMM2,XMM02987 PSRLW XMM2,82988 PACKUSWB XMM2,XMM32989 MOVD EAX, XMM22990 2991 @2: MOV [RDX],EAX2992 2993 @3: ADD RCX,42994 ADD RDX,42995 2996 DEC R8D2997 JNZ @12998 2999 @4:3000 {$ENDIF}3001 end;3002 3003 3004 procedure BlendLineEx_SSE2(Src, Dst: PColor32; Count: Integer; M: TColor32);3005 asm3006 {$IFDEF TARGET_X86}3007 // EAX <- Src3008 // EDX <- Dst3009 // ECX <- Count3010 3011 // test the counter for zero or negativity3012 TEST ECX,ECX3013 JS @43014 3015 PUSH ESI3016 PUSH EDI3017 PUSH EBX3018 3019 MOV ESI,EAX // ESI <- Src3020 MOV EDI,EDX // EDI <- Dst3021 MOV EDX,M // EDX <- Master Alpha3022 3023 // loop start3024 @1: MOV EAX,[ESI]3025 TEST EAX,$FF0000003026 JZ @3 // complete transparency, proceed to next point3027 MOV EBX,EAX3028 SHR EBX,243029 INC EBX // 255:256 range bias3030 IMUL EBX,EDX3031 SHR EBX,83032 JZ @3 // complete transparency, proceed to next point3033 3034 // blend3035 PXOR XMM0,XMM03036 MOVD XMM1,EAX3037 SHL EBX,43038 MOVD XMM2,[EDI]3039 PUNPCKLBW XMM1,XMM03040 PUNPCKLBW XMM2,XMM03041 ADD EBX,alpha_ptr3042 PSUBW XMM1,XMM23043 PMULLW XMM1,[EBX]3044 PSLLW XMM2,83045 MOV EBX,bias_ptr3046 PADDW XMM2,[EBX]3047 PADDW XMM1,XMM23048 PSRLW XMM1,83049 PACKUSWB XMM1,XMM03050 MOVD EAX,XMM13051 3052 @2: MOV [EDI],EAX3053 3054 @3: ADD ESI,43055 ADD EDI,43056 3057 // loop end3058 DEC ECX3059 JNZ @13060 3061 POP EBX3062 POP EDI3063 POP ESI3064 @4:3065 {$ENDIF}3066 3067 {$IFDEF TARGET_X64}3068 // ECX <- Src3069 // EDX <- Dst3070 // R8D <- Count3071 // R9D <- M3072 3073 // test the counter for zero or negativity3074 TEST R8D,R8D3075 JS @43076 TEST R9D,R9D3077 JZ @43078 3079 MOV R10,RCX // ESI <- Src3080 3081 // loop start3082 @1: MOV ECX,[R10]3083 TEST ECX,$FF0000003084 JZ @3 // complete transparency, proceed to next point3085 MOV EAX,ECX3086 SHR EAX,243087 INC EAX // 255:256 range bias3088 IMUL EAX,R9D3089 SHR EAX,83090 JZ @3 // complete transparency, proceed to next point3091 3092 // blend3093 PXOR XMM0,XMM03094 MOVD XMM1,ECX3095 SHL EAX,43096 MOVD XMM2,[RDX]3097 PUNPCKLBW XMM1,XMM03098 PUNPCKLBW XMM2,XMM03099 ADD RAX,alpha_ptr3100 PSUBW XMM1,XMM23101 PMULLW XMM1,[RAX]3102 PSLLW XMM2,83103 MOV RAX,bias_ptr3104 PADDW XMM2,[RAX]3105 PADDW XMM1,XMM23106 PSRLW XMM1,83107 PACKUSWB XMM1,XMM03108 MOVD ECX,XMM13109 3110 @2: MOV [RDX],ECX3111 3112 @3: ADD R10,43113 ADD RDX,43114 3115 // loop end3116 DEC R8D3117 JNZ @13118 @4:3119 {$ENDIF}3120 end;3121 3122 function CombineReg_SSE2(X, Y, W: TColor32): TColor32;3123 asm3124 {$IFDEF TARGET_X86}3125 // EAX - Color X3126 // EDX - Color Y3127 // ECX - Weight of X [0..255]3128 // Result := W * (X - Y) + Y3129 3130 MOVD XMM1,EAX3131 PXOR XMM0,XMM03132 SHL ECX,43133 3134 MOVD XMM2,EDX3135 PUNPCKLBW XMM1,XMM03136 PUNPCKLBW XMM2,XMM03137 3138 ADD ECX,alpha_ptr3139 3140 PSUBW XMM1,XMM23141 PMULLW XMM1,[ECX]3142 PSLLW XMM2,83143 3144 MOV ECX,bias_ptr3145 3146 PADDW XMM2,[ECX]3147 PADDW XMM1,XMM23148 PSRLW XMM1,83149 PACKUSWB XMM1,XMM03150 MOVD EAX,XMM13151 {$ENDIF}3152 3153 {$IFDEF TARGET_X64}3154 // ECX - Color X3155 // EDX - Color Y3156 // R8D - Weight of X [0..255]3157 // Result := W * (X - Y) + Y3158 3159 MOVD XMM1,ECX3160 PXOR XMM0,XMM03161 SHL R8D,43162 3163 MOVD XMM2,EDX3164 PUNPCKLBW XMM1,XMM03165 PUNPCKLBW XMM2,XMM03166 3167 ADD R8,alpha_ptr3168 3169 PSUBW XMM1,XMM23170 PMULLW XMM1,[R8]3171 PSLLW XMM2,83172 3173 MOV R8,bias_ptr3174 3175 PADDW XMM2,[R8]3176 PADDW XMM1,XMM23177 PSRLW XMM1,83178 PACKUSWB XMM1,XMM03179 MOVD EAX,XMM13180 {$ENDIF}3181 end;3182 3183 procedure CombineMem_SSE2(F: TColor32; var B: TColor32; W: TColor32);3184 asm3185 {$IFDEF TARGET_X86}3186 // EAX - Color X3187 // [EDX] - Color Y3188 // ECX - Weight of X [0..255]3189 // Result := W * (X - Y) + Y3190 3191 JCXZ @13192 3193 CMP ECX,$FF3194 JZ @23195 3196 MOVD XMM1,EAX3197 PXOR XMM0,XMM03198 3199 SHL ECX,43200 3201 MOVD XMM2,[EDX]3202 PUNPCKLBW XMM1,XMM03203 PUNPCKLBW XMM2,XMM03204 3205 ADD ECX,alpha_ptr3206 3207 PSUBW XMM1,XMM23208 PMULLW XMM1,[ECX]3209 PSLLW XMM2,83210 3211 MOV ECX,bias_ptr3212 3213 PADDW XMM2,[ECX]3214 PADDW XMM1,XMM23215 PSRLW XMM1,83216 PACKUSWB XMM1,XMM03217 MOVD [EDX],XMM13218 3219 {$IFDEF FPC}3220 @1: JMP @33221 {$ELSE}3222 @1: RET3223 {$ENDIF}3224 3225 @2: MOV [EDX],EAX3226 @3:3227 {$ENDIF}3228 3229 {$IFDEF TARGET_X64}3230 // ECX - Color X3231 // [RDX] - Color Y3232 // R8D - Weight of X [0..255]3233 // Result := W * (X - Y) + Y3234 3235 TEST R8D,R8D // Set flags for R83236 JZ @1 // W = 0 ? => Result := EDX3237 CMP R8D,$FF3238 JZ @23239 3240 MOVD XMM1,ECX3241 PXOR XMM0,XMM03242 3243 SHL R8D,43244 3245 MOVD XMM2,[RDX]3246 PUNPCKLBW XMM1,XMM03247 PUNPCKLBW XMM2,XMM03248 3249 ADD R8,alpha_ptr3250 3251 PSUBW XMM1,XMM23252 PMULLW XMM1,[R8]3253 PSLLW XMM2,83254 3255 MOV RAX,bias_ptr3256 3257 PADDW XMM2,[RAX]3258 PADDW XMM1,XMM23259 PSRLW XMM1,83260 PACKUSWB XMM1,XMM03261 MOVD [RDX],XMM13262 3263 {$IFDEF FPC}3264 @1: JMP @33265 {$ELSE}3266 @1: RET3267 {$ENDIF}3268 3269 @2: MOV [RDX],ECX3270 @3:3271 {$ENDIF}3272 end;3273 3274 3275 procedure CombineLine_SSE2(Src, Dst: PColor32; Count: Integer; W: TColor32);3276 asm3277 {$IFDEF TARGET_X86}3278 // EAX <- Src3279 // EDX <- Dst3280 // ECX <- Count3281 3282 // Result := W * (X - Y) + Y3283 3284 TEST ECX,ECX3285 JZ @33286 3287 PUSH EBX3288 MOV EBX,W3289 3290 TEST EBX,EBX3291 JZ @23292 3293 CMP EBX,$FF3294 JZ @43295 3296 SHL EBX,43297 ADD EBX,alpha_ptr3298 MOVQ XMM3,[EBX]3299 MOV EBX,bias_ptr3300 MOVQ XMM4,[EBX]3301 3302 @1: MOVD XMM1,[EAX]3303 PXOR XMM0,XMM03304 MOVD XMM2,[EDX]3305 PUNPCKLBW XMM1,XMM03306 PUNPCKLBW XMM2,XMM03307 3308 PSUBW XMM1,XMM23309 PMULLW XMM1,XMM33310 PSLLW XMM2,83311 3312 PADDW XMM2,XMM43313 PADDW XMM1,XMM23314 PSRLW XMM1,83315 PACKUSWB XMM1,XMM03316 MOVD [EDX],XMM13317 3318 ADD EAX,43319 ADD EDX,43320 3321 DEC ECX3322 JNZ @13323 3324 @2: POP EBX3325 POP EBP3326 3327 @3: RET $00043328 3329 @4: SHL ECX,23330 CALL Move3331 POP EBX3332 {$ENDIF}3333 3334 {$IFDEF TARGET_X64}3335 // ECX <- Src3336 // EDX <- Dst3337 // R8D <- Count3338 3339 // Result := W * (X - Y) + Y3340 3341 TEST R8D,R8D3342 JZ @23343 3344 TEST R9D,R9D3345 JZ @23346 3347 CMP R9D,$FF3348 JZ @33349 3350 SHL R9D,43351 ADD R9,alpha_ptr3352 MOVQ XMM3,[R9]3353 MOV R9,bias_ptr3354 MOVQ XMM4,[R9]3355 3356 @1: MOVD XMM1,[RCX]3357 PXOR XMM0,XMM03358 MOVD XMM2,[RDX]3359 PUNPCKLBW XMM1,XMM03360 PUNPCKLBW XMM2,XMM03361 3362 PSUBW XMM1,XMM23363 PMULLW XMM1,XMM33364 PSLLW XMM2,83365 3366 PADDW XMM2,XMM43367 PADDW XMM1,XMM23368 PSRLW XMM1,83369 PACKUSWB XMM1,XMM03370 MOVD [RDX],XMM13371 3372 ADD RCX,43373 ADD RDX,43374 3375 DEC R8D3376 JNZ @13377 3378 {$IFDEF FPC}3379 @2: JMP @43380 {$ELSE}3381 @2: RET3382 {$ENDIF}3383 3384 @3: SHL R8D,23385 CALL Move3386 @4:3387 {$ENDIF}3388 end;3389 3390 function MergeReg_SSE2(F, B: TColor32): TColor32;3391 asm3392 { This is an implementation of the merge formula, as described3393 in a paper by Bruce Wallace in 1981. Merging is associative,3394 that is, A over (B over C) = (A over B) over C. The formula is,3395 3396 Ra = Fa + Ba - Fa * Ba3397 Rc = (Fa (Fc - Bc * Ba) + Bc * Ba) / Ra3398 3399 where3400 3401 Rc is the resultant color,3402 Ra is the resultant alpha,3403 Fc is the foreground color,3404 Fa is the foreground alpha,3405 Bc is the background color,3406 Ba is the background alpha.3407 3408 Implementation:3409 3410 Ra := 1 - (1 - Fa) * (1 - Ba);3411 Wa := Fa / Ra;3412 Rc := Bc + Wa * (Fc - Bc);3413 // Rc := Bc + Wa * (Fc - Bc)3414 3415 (1 - Fa) * (1 - Ba) = 1 - Fa - Ba + Fa * Ba = (1 - Ra)3416 }3417 3418 {$IFDEF TARGET_X86}3419 TEST EAX,$FF000000 // foreground completely transparent =>3420 JZ @1 // result = background3421 CMP EAX,$FF000000 // foreground completely opaque =>3422 JNC @2 // result = foreground3423 TEST EDX,$FF000000 // background completely transparent =>3424 JZ @2 // result = foreground3425 3426 PXOR XMM7,XMM7 // XMM7 <- 003427 MOVD XMM0,EAX // XMM0 <- Fa Fr Fg Fb3428 SHR EAX,24 // EAX <- Fa3429 ROR EDX,243430 MOVZX ECX,DL // ECX <- Ba3431 PUNPCKLBW XMM0,XMM7 // XMM0 <- 00 Fa 00 Fr 00 Fg 00 Fb3432 SUB EAX,$FF // EAX <- (Fa - 1)3433 XOR ECX,$FF // ECX <- (1 - Ba)3434 IMUL ECX,EAX // ECX <- (Fa - 1) * (1 - Ba) = Ra - 13435 IMUL ECX,$8081 // ECX <- Xa 00 00 003436 ADD ECX,$8081*$FF*$FF3437 SHR ECX,15 // ECX <- Ra3438 MOV DL,CH // EDX <- Br Bg Bb Ra3439 ROR EDX,8 // EDX <- Ra Br Bg Bb3440 MOVD XMM1,EDX // XMM1 <- Ra Br Bg Bb3441 PUNPCKLBW XMM1,XMM7 // XMM1 <- 00 Ra 00 Br 00 Bg 00 Bb3442 SHL EAX,20 // EAX <- Fa 00 003443 PSUBW XMM0,XMM1 // XMM0 <- ** Da ** Dr ** Dg ** Db3444 ADD EAX,$0FF010003445 PSLLW XMM0,43446 XOR EDX,EDX // EDX <- 003447 DIV ECX // EAX <- Fa / Ra = Wa3448 MOVD XMM4,EAX // XMM3 <- Wa3449 PSHUFLW XMM4,XMM4,$C0 // XMM3 <- 00 00 ** Wa ** Wa ** Wa3450 PMULHW XMM0,XMM4 // XMM0 <- 00 00 ** Pr ** Pg ** Pb3451 PADDW XMM0,XMM1 // XMM0 <- 00 Ra 00 Rr 00 Rg 00 Rb3452 PACKUSWB XMM0,XMM7 // XMM0 <- Ra Rr Rg Rb3453 MOVD EAX,XMM03454 3455 {$IFDEF FPC}3456 JMP @23457 {$ELSE}3458 RET3459 {$ENDIF}3460 @1: MOV EAX,EDX3461 @2:3462 {$ENDIF}3463 3464 {$IFDEF TARGET_X64}3465 TEST ECX,$FF000000 // foreground completely transparent =>3466 JZ @1 // result = background3467 MOV EAX,ECX // EAX <- Fa3468 CMP EAX,$FF000000 // foreground completely opaque =>3469 JNC @2 // result = foreground3470 TEST EDX,$FF000000 // background completely transparent =>3471 JZ @2 // result = foreground3472 3473 PXOR XMM7,XMM7 // XMM7 <- 003474 MOVD XMM0,EAX // XMM0 <- Fa Fr Fg Fb3475 SHR EAX,24 // EAX <- Fa3476 ROR EDX,243477 MOVZX ECX,DL // ECX <- Ba3478 PUNPCKLBW XMM0,XMM7 // XMM0 <- 00 Fa 00 Fr 00 Fg 00 Fb3479 SUB EAX,$FF // EAX <- (Fa - 1)3480 XOR ECX,$FF // ECX <- (1 - Ba)3481 IMUL ECX,EAX // ECX <- (Fa - 1) * (1 - Ba) = Ra - 13482 IMUL ECX,$8081 // ECX <- Xa 00 00 003483 ADD ECX,$8081*$FF*$FF3484 SHR ECX,15 // ECX <- Ra3485 MOV DL,CH // EDX <- Br Bg Bb Ra3486 ROR EDX,8 // EDX <- Ra Br Bg Bb3487 MOVD XMM1,EDX // XMM1 <- Ra Br Bg Bb3488 PUNPCKLBW XMM1,XMM7 // XMM1 <- 00 Ra 00 Br 00 Bg 00 Bb3489 SHL EAX,20 // EAX <- Fa 00 003490 PSUBW XMM0,XMM1 // XMM0 <- ** Da ** Dr ** Dg ** Db3491 ADD EAX,$0FF010003492 PSLLW XMM0,43493 XOR EDX,EDX // EDX <- 003494 DIV ECX // EAX <- Fa / Ra = Wa3495 MOVD XMM4,EAX // XMM3 <- Wa3496 PSHUFLW XMM4,XMM4,$C0 // XMM3 <- 00 00 ** Wa ** Wa ** Wa3497 PMULHW XMM0,XMM4 // XMM0 <- 00 00 ** Pr ** Pg ** Pb3498 PADDW XMM0,XMM1 // XMM0 <- 00 Ra 00 Rr 00 Rg 00 Rb3499 PACKUSWB XMM0,XMM7 // XMM0 <- Ra Rr Rg Rb3500 MOVD EAX,XMM03501 3502 {$IFDEF FPC}3503 JMP @23504 {$ELSE}3505 RET3506 {$ENDIF}3507 @1: MOV EAX,EDX3508 @2:3509 {$ENDIF}3510 end;3511 3512 procedure EMMS_SSE2;3513 asm3514 end;3515 3516 3517 function LightenReg_SSE2(C: TColor32; Amount: Integer): TColor32;3518 asm3519 {$IFDEF TARGET_X86}3520 MOVD XMM0,EAX3521 TEST EDX,EDX3522 JL @13523 IMUL EDX,$0101013524 MOVD XMM1,EDX3525 PADDUSB XMM0,XMM13526 MOVD EAX,XMM03527 RET3528 @1: NEG EDX3529 IMUL EDX,$0101013530 MOVD XMM1,EDX3531 PSUBUSB XMM0,XMM13532 MOVD EAX,XMM03533 {$ENDIF}3534 3535 {$IFDEF TARGET_X64}3536 MOVD XMM0,ECX3537 TEST EDX,EDX3538 JL @13539 IMUL EDX,$0101013540 MOVD XMM1,EDX3541 PADDUSB XMM0,XMM13542 MOVD EAX,XMM03543 RET3544 @1: NEG EDX3545 IMUL EDX,$0101013546 MOVD XMM1,EDX3547 PSUBUSB XMM0,XMM13548 MOVD EAX,XMM03549 {$ENDIF}3550 end;3551 3552 3553 { SSE2 Color algebra}3554 3555 function ColorAdd_SSE2(C1, C2: TColor32): TColor32;3556 asm3557 {$IFDEF TARGET_X86}3558 MOVD XMM0,EAX3559 MOVD XMM1,EDX3560 PADDUSB XMM0,XMM13561 MOVD EAX,XMM03562 {$ENDIF}3563 3564 {$IFDEF TARGET_X64}3565 MOVD XMM0,ECX3566 MOVD XMM1,EDX3567 PADDUSB XMM0,XMM13568 MOVD EAX,XMM03569 {$ENDIF}3570 end;3571 3572 function ColorSub_SSE2(C1, C2: TColor32): TColor32;3573 asm3574 {$IFDEF TARGET_X86}3575 MOVD XMM0,EAX3576 MOVD XMM1,EDX3577 PSUBUSB XMM0,XMM13578 MOVD EAX,XMM03579 {$ENDIF}3580 3581 {$IFDEF TARGET_X64}3582 MOVD XMM0,ECX3583 MOVD XMM1,EDX3584 PSUBUSB XMM0,XMM13585 MOVD EAX,XMM03586 {$ENDIF}3587 end;3588 3589 function ColorModulate_SSE2(C1, C2: TColor32): TColor32;3590 asm3591 {$IFDEF TARGET_X86}3592 PXOR XMM2,XMM23593 MOVD XMM0,EAX3594 PUNPCKLBW XMM0,XMM23595 MOVD XMM1,EDX3596 PUNPCKLBW XMM1,XMM23597 PMULLW XMM0,XMM13598 PSRLW XMM0,83599 PACKUSWB XMM0,XMM23600 MOVD EAX,XMM03601 {$ENDIF}3602 3603 {$IFDEF TARGET_X64}3604 PXOR XMM2,XMM23605 MOVD XMM0,ECX3606 PUNPCKLBW XMM0,XMM23607 MOVD XMM1,EDX3608 PUNPCKLBW XMM1,XMM23609 PMULLW XMM0,XMM13610 PSRLW XMM0,83611 PACKUSWB XMM0,XMM23612 MOVD EAX,XMM03613 {$ENDIF}3614 end;3615 3616 function ColorMax_SSE2(C1, C2: TColor32): TColor32;3617 asm3618 {$IFDEF TARGET_X86}3619 MOVD XMM0,EAX3620 MOVD XMM1,EDX3621 PMAXUB XMM0,XMM13622 MOVD EAX,XMM03623 {$ENDIF}3624 3625 {$IFDEF TARGET_X64}3626 MOVD XMM0,ECX3627 MOVD XMM1,EDX3628 PMAXUB XMM0,XMM13629 MOVD EAX,XMM03630 {$ENDIF}3631 end;3632 3633 function ColorMin_SSE2(C1, C2: TColor32): TColor32;3634 asm3635 {$IFDEF TARGET_X86}3636 MOVD XMM0,EAX3637 MOVD XMM1,EDX3638 PMINUB XMM0,XMM13639 MOVD EAX,XMM03640 {$ENDIF}3641 3642 {$IFDEF TARGET_X64}3643 MOVD XMM0,ECX3644 MOVD XMM1,EDX3645 PMINUB XMM0,XMM13646 MOVD EAX,XMM03647 {$ENDIF}3648 end;3649 3650 function ColorDifference_SSE2(C1, C2: TColor32): TColor32;3651 asm3652 {$IFDEF TARGET_X86}3653 MOVD XMM0,EAX3654 MOVD XMM1,EDX3655 MOVQ XMM2,XMM03656 PSUBUSB XMM0,XMM13657 PSUBUSB XMM1,XMM23658 POR XMM0,XMM13659 MOVD EAX,XMM03660 {$ENDIF}3661 3662 {$IFDEF TARGET_X64}3663 MOVD XMM0,ECX3664 MOVD XMM1,EDX3665 MOVQ XMM2,XMM03666 PSUBUSB XMM0,XMM13667 PSUBUSB XMM1,XMM23668 POR XMM0,XMM13669 MOVD EAX,XMM03670 {$ENDIF}3671 end;3672 3673 function ColorExclusion_SSE2(C1, C2: TColor32): TColor32;3674 asm3675 {$IFDEF TARGET_X86}3676 PXOR XMM2,XMM23677 MOVD XMM0,EAX3678 PUNPCKLBW XMM0,XMM23679 MOVD XMM1,EDX3680 PUNPCKLBW XMM1,XMM23681 MOVQ XMM3,XMM03682 PADDW XMM0,XMM13683 PMULLW XMM1,XMM33684 PSRLW XMM1,73685 PSUBUSW XMM0,XMM13686 PACKUSWB XMM0,XMM23687 MOVD EAX,XMM03688 {$ENDIF}3689 3690 {$IFDEF TARGET_X64}3691 PXOR XMM2,XMM23692 MOVD XMM0,ECX3693 PUNPCKLBW XMM0,XMM23694 MOVD XMM1,EDX3695 PUNPCKLBW XMM1,XMM23696 MOVQ XMM3,XMM03697 PADDW XMM0,XMM13698 PMULLW XMM1,XMM33699 PSRLW XMM1,73700 PSUBUSW XMM0,XMM13701 PACKUSWB XMM0,XMM23702 MOVD EAX,XMM03703 {$ENDIF}3704 end;3705 3706 function ColorScale_SSE2(C, W: TColor32): TColor32;3707 asm3708 {$IFDEF TARGET_X86}3709 PXOR XMM2,XMM23710 SHL EDX,43711 MOVD XMM0,EAX3712 PUNPCKLBW XMM0,XMM23713 ADD EDX,alpha_ptr3714 PMULLW XMM0,[EDX]3715 PSRLW XMM0,83716 PACKUSWB XMM0,XMM23717 MOVD EAX,XMM03718 {$ENDIF}3719 3720 {$IFDEF TARGET_X64}3721 PXOR XMM2,XMM23722 SHL RDX,43723 MOVD XMM0,ECX3724 PUNPCKLBW XMM0,XMM23725 ADD RDX,alpha_ptr3726 PMULLW XMM0,[RDX]3727 PSRLW XMM0,83728 PACKUSWB XMM0,XMM23729 MOVD EAX,XMM03730 {$ENDIF}3731 end;3732 3733 {$ENDIF}3734 897 {$ENDIF} 3735 898 … … 3744 907 var 3745 908 I, J: Integer; 3746 const3747 OneByteth : Double = 1 / 255;3748 909 begin 3749 910 for J := 0 to 255 do 3750 for I := 0 to 255 do 911 begin 912 DivTable[0, J] := 0; 913 RcTable[0, J] := 0; 914 end; 915 for J := 0 to 255 do 916 for I := 1 to 255 do 3751 917 begin 3752 DivTable[I, J] := Round(I * J * OneByteth); 3753 if I > 0 then 3754 RcTable[I, J] := Round(J * 255 / I) 3755 else 3756 RcTable[I, J] := 0; 918 DivTable[I, J] := Round(I * J * COne255th); 919 RcTable[I, J] := Round(J * 255 / I) 3757 920 end; 3758 921 end; … … 3763 926 FID_MERGEMEM = 2; 3764 927 FID_MERGELINE = 3; 3765 FID_MERGEREGEX = 4; 3766 FID_MERGEMEMEX = 5; 3767 FID_MERGELINEEX = 6; 3768 FID_COMBINEREG = 7; 3769 FID_COMBINEMEM = 8; 3770 FID_COMBINELINE = 9; 3771 3772 FID_BLENDREG = 10; 3773 FID_BLENDMEM = 11; 3774 FID_BLENDLINE = 12; 3775 FID_BLENDREGEX = 13; 3776 FID_BLENDMEMEX = 14; 3777 FID_BLENDLINEEX = 15; 3778 3779 FID_COLORMAX = 16; 3780 FID_COLORMIN = 17; 3781 FID_COLORAVERAGE = 18; 3782 FID_COLORADD = 19; 3783 FID_COLORSUB = 20; 3784 FID_COLORDIV = 21; 3785 FID_COLORMODULATE = 22; 3786 FID_COLORDIFFERENCE = 23; 3787 FID_COLOREXCLUSION = 24; 3788 FID_COLORSCALE = 25; 3789 FID_Lighten = 26; 928 FID_MERGELINE1 = 4; 929 FID_MERGEREGEX = 5; 930 FID_MERGEMEMEX = 6; 931 FID_MERGELINEEX = 7; 932 FID_COMBINEREG = 8; 933 FID_COMBINEMEM = 9; 934 FID_COMBINELINE = 10; 935 936 FID_BLENDREG = 11; 937 FID_BLENDMEM = 12; 938 FID_BLENDMEMS = 13; 939 FID_BLENDLINE = 14; 940 FID_BLENDREGEX = 15; 941 FID_BLENDMEMEX = 16; 942 FID_BLENDLINEEX = 17; 943 FID_BLENDLINE1 = 18; 944 945 FID_COLORMAX = 19; 946 FID_COLORMIN = 20; 947 FID_COLORAVERAGE = 21; 948 FID_COLORADD = 22; 949 FID_COLORSUB = 23; 950 FID_COLORDIV = 24; 951 FID_COLORMODULATE = 25; 952 FID_COLORDIFFERENCE = 26; 953 FID_COLOREXCLUSION = 27; 954 FID_COLORSCALE = 28; 955 FID_COLORSCREEN = 29; 956 FID_COLORDODGE = 30; 957 FID_COLORBURN = 31; 958 FID_BLENDCOLORADD = 32; 959 FID_BLENDCOLORMODULATE = 33; 960 FID_LIGHTEN = 34; 961 962 FID_BLENDREGRGB = 35; 963 FID_BLENDMEMRGB = 36; 964 {$IFDEF TEST_BLENDMEMRGB128SSE4} 965 FID_BLENDMEMRGB128 = 37; 966 {$ENDIF} 967 968 const 969 BlendBindingFlagPascal = $0001; 970 3790 971 3791 972 procedure RegisterBindings; … … 3807 988 BlendRegistry.RegisterBinding(FID_BLENDREG, @@BlendReg); 3808 989 BlendRegistry.RegisterBinding(FID_BLENDMEM, @@BlendMem); 990 BlendRegistry.RegisterBinding(FID_BLENDMEMS, @@BlendMems); 3809 991 BlendRegistry.RegisterBinding(FID_BLENDLINE, @@BlendLine); 3810 992 BlendRegistry.RegisterBinding(FID_BLENDREGEX, @@BlendRegEx); 3811 993 BlendRegistry.RegisterBinding(FID_BLENDMEMEX, @@BlendMemEx); 3812 994 BlendRegistry.RegisterBinding(FID_BLENDLINEEX, @@BlendLineEx); 995 BlendRegistry.RegisterBinding(FID_BLENDLINE1, @@BlendLine1); 3813 996 3814 997 BlendRegistry.RegisterBinding(FID_COLORMAX, @@ColorMax); … … 3822 1005 BlendRegistry.RegisterBinding(FID_COLOREXCLUSION, @@ColorExclusion); 3823 1006 BlendRegistry.RegisterBinding(FID_COLORSCALE, @@ColorScale); 1007 BlendRegistry.RegisterBinding(FID_COLORSCREEN, @@ColorScreen); 1008 BlendRegistry.RegisterBinding(FID_COLORDODGE, @@ColorDodge); 1009 BlendRegistry.RegisterBinding(FID_COLORBURN, @@ColorBurn); 1010 1011 BlendRegistry.RegisterBinding(FID_BLENDCOLORADD, @@BlendColorAdd); 1012 BlendRegistry.RegisterBinding(FID_BLENDCOLORMODULATE, @@BlendColorModulate); 3824 1013 3825 1014 BlendRegistry.RegisterBinding(FID_LIGHTEN, @@LightenReg); 1015 BlendRegistry.RegisterBinding(FID_BLENDREGRGB, @@BlendRegRGB); 1016 BlendRegistry.RegisterBinding(FID_BLENDMEMRGB, @@BlendMemRGB); 1017 {$IFDEF TEST_BLENDMEMRGB128SSE4} 1018 BlendRegistry.RegisterBinding(FID_BLENDMEMRGB128, @@BlendMemRGB128); 1019 {$ENDIF} 3826 1020 3827 1021 // pure pascal 3828 BlendRegistry.Add(FID_EMMS, @EMMS_Pas); 3829 BlendRegistry.Add(FID_MERGEREG, @MergeReg_Pas); 3830 BlendRegistry.Add(FID_MERGEMEM, @MergeMem_Pas); 3831 BlendRegistry.Add(FID_MERGEMEMEX, @MergeMemEx_Pas); 3832 BlendRegistry.Add(FID_MERGEREGEX, @MergeRegEx_Pas); 3833 BlendRegistry.Add(FID_MERGELINE, @MergeLine_Pas); 3834 BlendRegistry.Add(FID_MERGELINEEX, @MergeLineEx_Pas); 3835 BlendRegistry.Add(FID_COLORDIV, @ColorDiv_Pas); 3836 BlendRegistry.Add(FID_COLORAVERAGE, @ColorAverage_Pas); 3837 BlendRegistry.Add(FID_COMBINEREG, @CombineReg_Pas); 3838 BlendRegistry.Add(FID_COMBINEMEM, @CombineMem_Pas); 3839 BlendRegistry.Add(FID_COMBINELINE, @CombineLine_Pas); 3840 BlendRegistry.Add(FID_BLENDREG, @BlendReg_Pas); 3841 BlendRegistry.Add(FID_BLENDMEM, @BlendMem_Pas); 3842 BlendRegistry.Add(FID_BLENDLINE, @BlendLine_Pas); 3843 BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_Pas); 3844 BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_Pas); 3845 BlendRegistry.Add(FID_BLENDLINEEX, @BlendLineEx_Pas); 3846 BlendRegistry.Add(FID_COLORMAX, @ColorMax_Pas); 3847 BlendRegistry.Add(FID_COLORMIN, @ColorMin_Pas); 3848 BlendRegistry.Add(FID_COLORADD, @ColorAdd_Pas); 3849 BlendRegistry.Add(FID_COLORSUB, @ColorSub_Pas); 3850 BlendRegistry.Add(FID_COLORMODULATE, @ColorModulate_Pas); 3851 BlendRegistry.Add(FID_COLORDIFFERENCE, @ColorDifference_Pas); 3852 BlendRegistry.Add(FID_COLOREXCLUSION, @ColorExclusion_Pas); 3853 BlendRegistry.Add(FID_COLORSCALE, @ColorScale_Pas); 3854 BlendRegistry.Add(FID_LIGHTEN, @LightenReg_Pas); 1022 BlendRegistry.Add(FID_EMMS, @EMMS_Pas, [], BlendBindingFlagPascal); 1023 BlendRegistry.Add(FID_MERGEREG, @MergeReg_Pas, [], BlendBindingFlagPascal); 1024 BlendRegistry.Add(FID_MERGEMEM, @MergeMem_Pas, [], BlendBindingFlagPascal); 1025 BlendRegistry.Add(FID_MERGEMEMEX, @MergeMemEx_Pas, [], BlendBindingFlagPascal); 1026 BlendRegistry.Add(FID_MERGEREGEX, @MergeRegEx_Pas, [], BlendBindingFlagPascal); 1027 BlendRegistry.Add(FID_MERGELINE, @MergeLine_Pas, [], BlendBindingFlagPascal); 1028 BlendRegistry.Add(FID_MERGELINEEX, @MergeLineEx_Pas, [], BlendBindingFlagPascal); 1029 BlendRegistry.Add(FID_MERGELINE1, @MergeLine1_Pas, [], BlendBindingFlagPascal); 1030 BlendRegistry.Add(FID_COLORDIV, @ColorDiv_Pas, [], BlendBindingFlagPascal); 1031 BlendRegistry.Add(FID_COLORAVERAGE, @ColorAverage_Pas, [], BlendBindingFlagPascal); 1032 BlendRegistry.Add(FID_COMBINEREG, @CombineReg_Pas, [], BlendBindingFlagPascal); 1033 BlendRegistry.Add(FID_COMBINEMEM, @CombineMem_Pas, [], BlendBindingFlagPascal); 1034 BlendRegistry.Add(FID_COMBINELINE, @CombineLine_Pas, [], BlendBindingFlagPascal); 1035 BlendRegistry.Add(FID_BLENDREG, @BlendReg_Pas, [], BlendBindingFlagPascal); 1036 BlendRegistry.Add(FID_BLENDMEM, @BlendMem_Pas, [], BlendBindingFlagPascal); 1037 BlendRegistry.Add(FID_BLENDMEMS, @BlendMems_Pas, [], BlendBindingFlagPascal); 1038 BlendRegistry.Add(FID_BLENDLINE, @BlendLine_Pas, [], BlendBindingFlagPascal); 1039 BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_Pas, [], BlendBindingFlagPascal); 1040 BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_Pas, [], BlendBindingFlagPascal); 1041 BlendRegistry.Add(FID_BLENDLINEEX, @BlendLineEx_Pas, [], BlendBindingFlagPascal); 1042 BlendRegistry.Add(FID_BLENDLINE1, @BlendLine1_Pas, [], BlendBindingFlagPascal); 1043 BlendRegistry.Add(FID_COLORMAX, @ColorMax_Pas, [], BlendBindingFlagPascal); 1044 BlendRegistry.Add(FID_COLORMIN, @ColorMin_Pas, [], BlendBindingFlagPascal); 1045 BlendRegistry.Add(FID_COLORADD, @ColorAdd_Pas, [], BlendBindingFlagPascal); 1046 BlendRegistry.Add(FID_COLORSUB, @ColorSub_Pas, [], BlendBindingFlagPascal); 1047 BlendRegistry.Add(FID_COLORMODULATE, @ColorModulate_Pas, [], BlendBindingFlagPascal); 1048 BlendRegistry.Add(FID_COLORDIFFERENCE, @ColorDifference_Pas, [], BlendBindingFlagPascal); 1049 BlendRegistry.Add(FID_COLOREXCLUSION, @ColorExclusion_Pas, [], BlendBindingFlagPascal); 1050 BlendRegistry.Add(FID_COLORSCALE, @ColorScale_Pas, [], BlendBindingFlagPascal); 1051 BlendRegistry.Add(FID_COLORSCREEN, @ColorScreen_Pas, [], BlendBindingFlagPascal); 1052 BlendRegistry.Add(FID_COLORDODGE, @ColorDodge_Pas, [], BlendBindingFlagPascal); 1053 BlendRegistry.Add(FID_COLORBURN, @ColorBurn_Pas, [], BlendBindingFlagPascal); 1054 BlendRegistry.Add(FID_BLENDCOLORADD, @BlendColorAdd_Pas, [], BlendBindingFlagPascal); 1055 BlendRegistry.Add(FID_BLENDCOLORMODULATE, @BlendColorModulate_Pas, [], BlendBindingFlagPascal); 1056 BlendRegistry.Add(FID_LIGHTEN, @LightenReg_Pas, [], BlendBindingFlagPascal); 1057 BlendRegistry.Add(FID_BLENDREGRGB, @BlendRegRGB_Pas, [], BlendBindingFlagPascal); 1058 BlendRegistry.Add(FID_BLENDMEMRGB, @BlendMemRGB_Pas, [], BlendBindingFlagPascal); 3855 1059 3856 1060 {$IFNDEF PUREPASCAL} … … 3860 1064 BlendRegistry.Add(FID_BLENDREG, @BlendReg_ASM, []); 3861 1065 BlendRegistry.Add(FID_BLENDMEM, @BlendMem_ASM, []); 1066 BlendRegistry.Add(FID_BLENDMEMS, @BlendMems_ASM, []); 3862 1067 BlendRegistry.Add(FID_BLENDREGEX, @BlendRegEx_ASM, []); 3863 1068 BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_ASM, []); 3864 1069 BlendRegistry.Add(FID_BLENDLINE, @BlendLine_ASM, []); 3865 BlendRegistry.Add(FID_LIGHTEN, @LightenReg_Pas, []); // no ASM version available 1070 BlendRegistry.Add(FID_BLENDLINE1, @BlendLine1_ASM, []); 1071 {$IFNDEF TARGET_x64} 1072 BlendRegistry.Add(FID_MERGEREG, @MergeReg_ASM, []); 1073 {$ENDIF} 3866 1074 {$IFNDEF OMIT_MMX} 3867 1075 BlendRegistry.Add(FID_EMMS, @EMMS_MMX, [ciMMX]); … … 3884 1092 BlendRegistry.Add(FID_COLORSCALE, @ColorScale_MMX, [ciMMX]); 3885 1093 BlendRegistry.Add(FID_LIGHTEN, @LightenReg_MMX, [ciMMX]); 1094 BlendRegistry.Add(FID_BLENDREGRGB, @BlendRegRGB_MMX, [ciMMX]); 1095 BlendRegistry.Add(FID_BLENDMEMRGB, @BlendMemRGB_MMX, [ciMMX]); 3886 1096 {$ENDIF} 3887 1097 {$IFNDEF OMIT_SSE2} … … 3893 1103 BlendRegistry.Add(FID_BLENDREG, @BlendReg_SSE2, [ciSSE2]); 3894 1104 BlendRegistry.Add(FID_BLENDMEM, @BlendMem_SSE2, [ciSSE2]); 1105 BlendRegistry.Add(FID_BLENDMEMS, @BlendMems_SSE2, [ciSSE2]); 3895 1106 BlendRegistry.Add(FID_BLENDMEMEX, @BlendMemEx_SSE2, [ciSSE2]); 3896 1107 BlendRegistry.Add(FID_BLENDLINE, @BlendLine_SSE2, [ciSSE2]); … … 3906 1117 BlendRegistry.Add(FID_COLORSCALE, @ColorScale_SSE2, [ciSSE2]); 3907 1118 BlendRegistry.Add(FID_LIGHTEN, @LightenReg_SSE2, [ciSSE]); 3908 {$ENDIF} 3909 {$IFNDEF TARGET_x64} 3910 BlendRegistry.Add(FID_MERGEREG, @MergeReg_ASM, []); 1119 BlendRegistry.Add(FID_BLENDREGRGB, @BlendRegRGB_SSE2, [ciSSE2]); 1120 BlendRegistry.Add(FID_BLENDMEMRGB, @BlendMemRGB_SSE2, [ciSSE2]); 1121 {$IFDEF TEST_BLENDMEMRGB128SSE4} 1122 BlendRegistry.Add(FID_BLENDMEMRGB128, @BlendMemRGB128_SSE4, [ciSSE2]); 1123 {$ENDIF} 3911 1124 {$ENDIF} 3912 1125 {$ENDIF} … … 3916 1129 3917 1130 initialization 1131 BlendColorAdd := BlendColorAdd_Pas; 1132 3918 1133 RegisterBindings; 3919 1134 MakeMergeTables; … … 3929 1144 finalization 3930 1145 {$IFNDEF PUREPASCAL} 3931 {$IFNDEF OMIT_MMX} 3932 if (ciMMX in CPUFeatures) then FreeAlphaTable; 3933 {$ENDIF} 1146 if [ciMMX, ciSSE2] * CPUFeatures <> [] then 1147 FreeAlphaTable; 3934 1148 {$ENDIF} 3935 1149
Note:
See TracChangeset
for help on using the changeset viewer.