Chromium Code Reviews| Index: src/opts/SkXfermode_opts_arm.cpp |
| diff --git a/src/opts/SkXfermode_opts_arm.cpp b/src/opts/SkXfermode_opts_arm.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bf9bae54f490c0738bf81217a04e27646bf386d5 |
| --- /dev/null |
| +++ b/src/opts/SkXfermode_opts_arm.cpp |
| @@ -0,0 +1,129 @@ |
| +#include "SkXfermode.h" |
| +#include "SkXfermode_proccoeff.h" |
| +#include "SkUtilsArm.h" |
| + |
| +#if !SK_ARM_NEON_IS_NONE |
| + |
| +#include <arm_neon.h> |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| + |
| +typedef uint8x8x4_t (*SkXfermodeProcSIMD)(uint8x8x4_t src, uint8x8x4_t dst); |
| + |
| +class SkNEONProcCoeffXfermode : public SkProcCoeffXfermode { |
| +public: |
| + SkNEONProcCoeffXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, |
| + SkXfermodeProcSIMD procSIMD) |
| + : INHERITED(rec, mode), fProcSIMD(procSIMD) {} |
| + |
| + virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, |
| + const SkAlpha aa[]) const SK_OVERRIDE; |
| +private: |
| + SkXfermodeProcSIMD fProcSIMD; |
| + typedef SkProcCoeffXfermode INHERITED; |
| +}; |
| + |
| + |
| +void SkNEONProcCoeffXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], |
| + int count, const SkAlpha aa[]) const { |
| + SkASSERT(dst && src && count >= 0); |
| + |
| + SkXfermodeProc proc = fProc; |
| + SkXfermodeProcSIMD procSIMD = fProcSIMD; |
| + |
| + if (NULL == aa) { |
| + // Unrolled NEON code |
| + while (count >= 8) { |
| + uint8x8x4_t vsrc, vdst, vres; |
| + |
| + asm volatile ( |
| + "vld4.u8 %h[vsrc], [%[src]]! \t\n" |
| + "vld4.u8 %h[vdst], [%[dst]] \t\n" |
| + : [vsrc] "=w" (vsrc), [vdst] "=w" (vdst) |
| + : [src] "r" (src), [dst] "r" (dst) |
| + : |
| + ); |
| + |
| + vres = procSIMD(vsrc, vdst); |
| + |
| + vst4_u8((uint8_t*)dst, vres); |
| + |
| + count -= 8; |
| + dst += 8; |
| + } |
| + // Leftovers |
| + for (int i = 0; i < count; i++) { |
| + dst[i] = proc(src[i], dst[i]); |
| + } |
| + } else { |
| + for (int i = count - 1; i >= 0; --i) { |
| + unsigned a = aa[i]; |
| + if (0 != a) { |
| + SkPMColor dstC = dst[i]; |
| + SkPMColor C = proc(src[i], dstC); |
| + if (a != 0xFF) { |
| + C = SkFourByteInterp(C, dstC, a); |
| + } |
| + dst[i] = C; |
| + } |
| + } |
| + } |
| +} |
| + |
| +#ifdef SK_DEVELOPER |
| +void SkNEONProcCoeffXfermode::toString(SkString* str) const { |
| + this->INHERITED::toString(str); |
| +} |
| +#endif |
| + |
| +//////////////////////////////////////////////////////////////////////////////// |
| + |
| +SkXfermodeProcSIMD gNEONXfermodeProcs[] = { |
| + [SkXfermode::kClear_Mode] = NULL, |
| + [SkXfermode::kSrc_Mode] = NULL, |
|
djsollen
2013/10/07 16:58:03
spacing
kevin.petit.not.used.account
2013/10/07 17:18:51
Done.
|
| + [SkXfermode::kDst_Mode] = NULL, |
| + [SkXfermode::kSrcOver_Mode] = NULL, |
| + [SkXfermode::kDstOver_Mode] = NULL, |
| + [SkXfermode::kSrcIn_Mode] = NULL, |
| + [SkXfermode::kDstIn_Mode] = NULL, |
| + [SkXfermode::kSrcOut_Mode] = NULL, |
| + [SkXfermode::kDstOut_Mode] = NULL, |
| + [SkXfermode::kSrcATop_Mode] = NULL, |
| + [SkXfermode::kDstATop_Mode] = NULL, |
| + [SkXfermode::kXor_Mode] = NULL, |
| + [SkXfermode::kPlus_Mode] = NULL, |
| + [SkXfermode::kModulate_Mode]= NULL, |
| + [SkXfermode::kScreen_Mode] = NULL, |
| + |
| + [SkXfermode::kOverlay_Mode] = NULL, |
| + [SkXfermode::kDarken_Mode] = NULL, |
| + [SkXfermode::kLighten_Mode] = NULL, |
| + [SkXfermode::kColorDodge_Mode] = NULL, |
| + [SkXfermode::kColorBurn_Mode] = NULL, |
| + [SkXfermode::kHardLight_Mode] = NULL, |
| + [SkXfermode::kSoftLight_Mode] = NULL, |
| + [SkXfermode::kDifference_Mode] = NULL, |
| + [SkXfermode::kExclusion_Mode] = NULL, |
| + [SkXfermode::kMultiply_Mode] = NULL, |
| + |
| + [SkXfermode::kHue_Mode] = NULL, |
| + [SkXfermode::kSaturation_Mode] = NULL, |
| + [SkXfermode::kColor_Mode] = NULL, |
| + [SkXfermode::kLuminosity_Mode] = NULL, |
| +}; |
|
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.
|
| +#endif |
| + |
| +SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, |
| + SkXfermode::Mode mode) { |
| +#if !SK_ARM_NEON_IS_NONE |
| + #if SK_ARM_NEON_IS_DYNAMIC |
| + if ((sk_cpu_arm_has_neon()) && (gNEONXfermodeProcs[mode] != NULL)) { |
| + #elif SK_ARM_NEON_IS_ALWAYS |
| + if (gNEONXfermodeProcs[mode] != NULL) { |
| + #endif |
| + return SkNEW_ARGS(SkNEONProcCoeffXfermode, |
| + (rec, mode, gNEONXfermodeProcs[mode])); |
| + } |
| +#endif |
| + return NULL; |
| +} |