OLD | NEW |
1 #include "SkXfermode.h" | 1 #include "SkXfermode.h" |
2 #include "SkXfermode_proccoeff.h" | 2 #include "SkXfermode_proccoeff.h" |
3 #include "SkColorPriv.h" | 3 #include "SkColorPriv.h" |
4 | 4 |
5 #include <arm_neon.h> | 5 #include <arm_neon.h> |
6 #include "SkColor_opts_neon.h" | 6 #include "SkColor_opts_neon.h" |
7 #include "SkXfermode_opts_arm_neon.h" | 7 #include "SkXfermode_opts_arm_neon.h" |
8 | 8 |
9 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) | 9 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) |
10 | 10 |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
567 : INHERITED(buffer) { | 567 : INHERITED(buffer) { |
568 fProcSIMD = reinterpret_cast<void*>(gNEONXfermodeProcs[this->getMode()]); | 568 fProcSIMD = reinterpret_cast<void*>(gNEONXfermodeProcs[this->getMode()]); |
569 } | 569 } |
570 | 570 |
571 void SkNEONProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], | 571 void SkNEONProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], |
572 int count, const SkAlpha aa[]) const { | 572 int count, const SkAlpha aa[]) const { |
573 SkASSERT(dst && src && count >= 0); | 573 SkASSERT(dst && src && count >= 0); |
574 | 574 |
575 SkXfermodeProc proc = this->getProc(); | 575 SkXfermodeProc proc = this->getProc(); |
576 SkXfermodeProcSIMD procSIMD = reinterpret_cast<SkXfermodeProcSIMD>(fProcSIMD
); | 576 SkXfermodeProcSIMD procSIMD = reinterpret_cast<SkXfermodeProcSIMD>(fProcSIMD
); |
| 577 SkASSERT(procSIMD != NULL); |
577 | 578 |
578 if (NULL == aa) { | 579 if (NULL == aa) { |
579 // Unrolled NEON code | 580 // Unrolled NEON code |
580 while (count >= 8) { | 581 while (count >= 8) { |
581 uint8x8x4_t vsrc, vdst, vres; | 582 uint8x8x4_t vsrc, vdst, vres; |
582 | 583 |
583 #if (__GNUC__ == 4) && (__GNUC_MINOR__ > 6) | 584 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)) |
584 asm volatile ( | 585 asm volatile ( |
585 "vld4.u8 %h[vsrc], [%[src]]! \t\n" | 586 "vld4.u8 %h[vsrc], [%[src]]! \t\n" |
586 "vld4.u8 %h[vdst], [%[dst]] \t\n" | 587 "vld4.u8 %h[vdst], [%[dst]] \t\n" |
587 : [vsrc] "=w" (vsrc), [vdst] "=w" (vdst), [src] "+&r" (src) | 588 : [vsrc] "=w" (vsrc), [vdst] "=w" (vdst), [src] "+&r" (src) |
588 : [dst] "r" (dst) | 589 : [dst] "r" (dst) |
589 : | 590 : |
590 ); | 591 ); |
591 #else | 592 #else |
592 register uint8x8_t d0 asm("d0"); | 593 register uint8x8_t d0 asm("d0"); |
593 register uint8x8_t d1 asm("d1"); | 594 register uint8x8_t d1 asm("d1"); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
632 SkPMColor C = proc(src[i], dstC); | 633 SkPMColor C = proc(src[i], dstC); |
633 if (a != 0xFF) { | 634 if (a != 0xFF) { |
634 C = SkFourByteInterp(C, dstC, a); | 635 C = SkFourByteInterp(C, dstC, a); |
635 } | 636 } |
636 dst[i] = C; | 637 dst[i] = C; |
637 } | 638 } |
638 } | 639 } |
639 } | 640 } |
640 } | 641 } |
641 | 642 |
| 643 void SkNEONProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst, |
| 644 const SkPMColor* SK_RESTRICT src, int count
, |
| 645 const SkAlpha* SK_RESTRICT aa) const { |
| 646 SkASSERT(dst && src && count >= 0); |
| 647 |
| 648 SkXfermodeProc proc = this->getProc(); |
| 649 SkXfermodeProcSIMD procSIMD = reinterpret_cast<SkXfermodeProcSIMD>(fProcSIMD
); |
| 650 SkASSERT(procSIMD != NULL); |
| 651 |
| 652 if (NULL == aa) { |
| 653 while(count >= 8) { |
| 654 uint16x8_t vdst, vres16; |
| 655 uint8x8x4_t vdst32, vsrc, vres; |
| 656 |
| 657 vdst = vld1q_u16(dst); |
| 658 |
| 659 #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6)) |
| 660 asm volatile ( |
| 661 "vld4.u8 %h[vsrc], [%[src]]! \t\n" |
| 662 : [vsrc] "=w" (vsrc), [src] "+&r" (src) |
| 663 : : |
| 664 ); |
| 665 #else |
| 666 register uint8x8_t d0 asm("d0"); |
| 667 register uint8x8_t d1 asm("d1"); |
| 668 register uint8x8_t d2 asm("d2"); |
| 669 register uint8x8_t d3 asm("d3"); |
| 670 |
| 671 asm volatile ( |
| 672 "vld4.u8 {d0-d3},[%[src]]!;" |
| 673 : "=w" (d0), "=w" (d1), "=w" (d2), "=w" (d3), |
| 674 [src] "+&r" (src) |
| 675 : : |
| 676 ); |
| 677 vsrc.val[0] = d0; |
| 678 vsrc.val[1] = d1; |
| 679 vsrc.val[2] = d2; |
| 680 vsrc.val[3] = d3; |
| 681 #endif |
| 682 |
| 683 vdst32 = SkPixel16ToPixel32_neon8(vdst); |
| 684 vres = procSIMD(vsrc, vdst32); |
| 685 vres16 = SkPixel32ToPixel16_neon8(vres); |
| 686 |
| 687 vst1q_u16(dst, vres16); |
| 688 |
| 689 count -= 8; |
| 690 dst += 8; |
| 691 } |
| 692 for (int i = 0; i < count; i++) { |
| 693 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); |
| 694 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC)); |
| 695 } |
| 696 } else { |
| 697 for (int i = count - 1; i >= 0; --i) { |
| 698 unsigned a = aa[i]; |
| 699 if (0 != a) { |
| 700 SkPMColor dstC = SkPixel16ToPixel32(dst[i]); |
| 701 SkPMColor C = proc(src[i], dstC); |
| 702 if (0xFF != a) { |
| 703 C = SkFourByteInterp(C, dstC, a); |
| 704 } |
| 705 dst[i] = SkPixel32ToPixel16_ToU16(C); |
| 706 } |
| 707 } |
| 708 } |
| 709 } |
| 710 |
642 #ifdef SK_DEVELOPER | 711 #ifdef SK_DEVELOPER |
643 void SkNEONProcCoeffXfermode::toString(SkString* str) const { | 712 void SkNEONProcCoeffXfermode::toString(SkString* str) const { |
644 this->INHERITED::toString(str); | 713 this->INHERITED::toString(str); |
645 } | 714 } |
646 #endif | 715 #endif |
647 | 716 |
648 //////////////////////////////////////////////////////////////////////////////// | 717 //////////////////////////////////////////////////////////////////////////////// |
649 | 718 |
650 SkXfermodeProcSIMD gNEONXfermodeProcs[] = { | 719 SkXfermodeProcSIMD gNEONXfermodeProcs[] = { |
651 NULL, // kClear_Mode | 720 NULL, // kClear_Mode |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 SkProcCoeffXfermode* SkPlatformXfermodeFactory_impl_neon(const ProcCoeff& rec, | 758 SkProcCoeffXfermode* SkPlatformXfermodeFactory_impl_neon(const ProcCoeff& rec, |
690 SkXfermode::Mode mode)
{ | 759 SkXfermode::Mode mode)
{ |
691 | 760 |
692 void* procSIMD = reinterpret_cast<void*>(gNEONXfermodeProcs[mode]); | 761 void* procSIMD = reinterpret_cast<void*>(gNEONXfermodeProcs[mode]); |
693 | 762 |
694 if (procSIMD != NULL) { | 763 if (procSIMD != NULL) { |
695 return SkNEW_ARGS(SkNEONProcCoeffXfermode, (rec, mode, procSIMD)); | 764 return SkNEW_ARGS(SkNEONProcCoeffXfermode, (rec, mode, procSIMD)); |
696 } | 765 } |
697 return NULL; | 766 return NULL; |
698 } | 767 } |
OLD | NEW |