Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #include "SkXfermode.h" | |
| 2 #include "SkXfermode_proccoeff.h" | |
| 3 #include "SkUtilsArm.h" | |
| 4 | |
| 5 #if !SK_ARM_NEON_IS_NONE | |
| 6 | |
| 7 #include <arm_neon.h> | |
| 8 | |
| 9 //////////////////////////////////////////////////////////////////////////////// | |
| 10 | |
| 11 typedef uint8x8x4_t (*SkXfermodeProcSIMD)(uint8x8x4_t src, uint8x8x4_t dst); | |
| 12 | |
| 13 class SkNEONProcCoeffXfermode : public SkProcCoeffXfermode { | |
| 14 public: | |
| 15 SkNEONProcCoeffXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, | |
| 16 SkXfermodeProcSIMD procSIMD) | |
| 17 : INHERITED(rec, mode), fProcSIMD(procSIMD) {} | |
| 18 | |
| 19 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, | |
| 20 const SkAlpha aa[]) const SK_OVERRIDE; | |
| 21 private: | |
| 22 SkXfermodeProcSIMD fProcSIMD; | |
| 23 typedef SkProcCoeffXfermode INHERITED; | |
| 24 }; | |
| 25 | |
| 26 | |
| 27 void SkNEONProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], | |
| 28 int count, const SkAlpha aa[]) const { | |
| 29 SkASSERT(dst && src && count >= 0); | |
| 30 | |
| 31 SkXfermodeProc proc = fProc; | |
| 32 SkXfermodeProcSIMD procSIMD = fProcSIMD; | |
| 33 | |
| 34 if (NULL == aa) { | |
| 35 // Unrolled NEON code | |
| 36 while (count >= 8) { | |
| 37 uint8x8x4_t vsrc, vdst, vres; | |
| 38 | |
| 39 asm volatile ( | |
| 40 "vld4.u8 %h[vsrc], [%[src]]! \t\n" | |
| 41 "vld4.u8 %h[vdst], [%[dst]] \t\n" | |
| 42 : [vsrc] "=w" (vsrc), [vdst] "=w" (vdst) | |
| 43 : [src] "r" (src), [dst] "r" (dst) | |
| 44 : | |
| 45 ); | |
| 46 | |
| 47 vres = procSIMD(vsrc, vdst); | |
| 48 | |
| 49 vst4_u8((uint8_t*)dst, vres); | |
| 50 | |
| 51 count -= 8; | |
| 52 dst += 8; | |
| 53 } | |
| 54 // Leftovers | |
| 55 for (int i = 0; i < count; i++) { | |
| 56 dst[i] = proc(src[i], dst[i]); | |
| 57 } | |
| 58 } else { | |
| 59 for (int i = count - 1; i >= 0; --i) { | |
| 60 unsigned a = aa[i]; | |
| 61 if (0 != a) { | |
| 62 SkPMColor dstC = dst[i]; | |
| 63 SkPMColor C = proc(src[i], dstC); | |
| 64 if (a != 0xFF) { | |
| 65 C = SkFourByteInterp(C, dstC, a); | |
| 66 } | |
| 67 dst[i] = C; | |
| 68 } | |
| 69 } | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 #ifdef SK_DEVELOPER | |
| 74 void SkNEONProcCoeffXfermode::toString(SkString* str) const { | |
| 75 this->INHERITED::toString(str); | |
| 76 } | |
| 77 #endif | |
| 78 | |
| 79 //////////////////////////////////////////////////////////////////////////////// | |
| 80 | |
| 81 SkXfermodeProcSIMD gNEONXfermodeProcs[] = { | |
| 82 [SkXfermode::kClear_Mode] = NULL, | |
| 83 [SkXfermode::kSrc_Mode] = NULL, | |
|
djsollen
2013/10/07 16:58:03
spacing
kevin.petit.not.used.account
2013/10/07 17:18:51
Done.
| |
| 84 [SkXfermode::kDst_Mode] = NULL, | |
| 85 [SkXfermode::kSrcOver_Mode] = NULL, | |
| 86 [SkXfermode::kDstOver_Mode] = NULL, | |
| 87 [SkXfermode::kSrcIn_Mode] = NULL, | |
| 88 [SkXfermode::kDstIn_Mode] = NULL, | |
| 89 [SkXfermode::kSrcOut_Mode] = NULL, | |
| 90 [SkXfermode::kDstOut_Mode] = NULL, | |
| 91 [SkXfermode::kSrcATop_Mode] = NULL, | |
| 92 [SkXfermode::kDstATop_Mode] = NULL, | |
| 93 [SkXfermode::kXor_Mode] = NULL, | |
| 94 [SkXfermode::kPlus_Mode] = NULL, | |
| 95 [SkXfermode::kModulate_Mode]= NULL, | |
| 96 [SkXfermode::kScreen_Mode] = NULL, | |
| 97 | |
| 98 [SkXfermode::kOverlay_Mode] = NULL, | |
| 99 [SkXfermode::kDarken_Mode] = NULL, | |
| 100 [SkXfermode::kLighten_Mode] = NULL, | |
| 101 [SkXfermode::kColorDodge_Mode] = NULL, | |
| 102 [SkXfermode::kColorBurn_Mode] = NULL, | |
| 103 [SkXfermode::kHardLight_Mode] = NULL, | |
| 104 [SkXfermode::kSoftLight_Mode] = NULL, | |
| 105 [SkXfermode::kDifference_Mode] = NULL, | |
| 106 [SkXfermode::kExclusion_Mode] = NULL, | |
| 107 [SkXfermode::kMultiply_Mode] = NULL, | |
| 108 | |
| 109 [SkXfermode::kHue_Mode] = NULL, | |
| 110 [SkXfermode::kSaturation_Mode] = NULL, | |
| 111 [SkXfermode::kColor_Mode] = NULL, | |
| 112 [SkXfermode::kLuminosity_Mode] = NULL, | |
| 113 }; | |
|
djsollen
2013/10/07 16:58:03
Add something like
SK_COMPILE_ASSERT(SK_ARRAY_COU
kevin.petit.not.used.account
2013/10/07 17:18:51
Done.
| |
| 114 #endif | |
| 115 | |
| 116 SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, | |
| 117 SkXfermode::Mode mode) { | |
| 118 #if !SK_ARM_NEON_IS_NONE | |
| 119 #if SK_ARM_NEON_IS_DYNAMIC | |
| 120 if ((sk_cpu_arm_has_neon()) && (gNEONXfermodeProcs[mode] != NULL)) { | |
| 121 #elif SK_ARM_NEON_IS_ALWAYS | |
| 122 if (gNEONXfermodeProcs[mode] != NULL) { | |
| 123 #endif | |
| 124 return SkNEW_ARGS(SkNEONProcCoeffXfermode, | |
| 125 (rec, mode, gNEONXfermodeProcs[mode])); | |
| 126 } | |
| 127 #endif | |
| 128 return NULL; | |
| 129 } | |
| OLD | NEW |