Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(979)

Unified Diff: src/opts/SkXfermode_opts_arm.cpp

Issue 23644006: ARM Skia NEON patches - 28 - Xfermode: SIMD modeprocs (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Fix android build + implement serialization Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkXfermode_proccoeff.h ('k') | src/opts/SkXfermode_opts_none.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..db5d5317e3d6f5bbb2b8da170b6d96cdbe2fa3e6
--- /dev/null
+++ b/src/opts/SkXfermode_opts_arm.cpp
@@ -0,0 +1,158 @@
+#include "SkXfermode.h"
+#include "SkXfermode_proccoeff.h"
+#include "SkColorPriv.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;
+
+ SK_DEVELOPER_TO_STRING()
+ SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNEONProcCoeffXfermode)
+
+private:
+ SkNEONProcCoeffXfermode(SkFlattenableReadBuffer& buffer)
+ : INHERITED(buffer) {
+
+ fProcSIMD = NULL;
+ if (!buffer.isCrossProcess()) {
+ fProcSIMD = (SkXfermodeProcSIMD)buffer.readFunctionPtr();
+ }
+ }
+
+ virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE;
+
+ 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 = this->getProc();
+ 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
+
+void SkNEONProcCoeffXfermode::flatten(SkFlattenableWriteBuffer& buffer) const {
+ this->INHERITED::flatten(buffer);
+ if (!buffer.isCrossProcess()) {
+ buffer.writeFunctionPtr((void*)fProcSIMD);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SkXfermodeProcSIMD gNEONXfermodeProcs[] = {
+ [SkXfermode::kClear_Mode] = NULL,
+ [SkXfermode::kSrc_Mode] = NULL,
+ [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,
+};
+
+SK_COMPILE_ASSERT(
+ SK_ARRAY_COUNT(gNEONXfermodeProcs) == SkXfermode::kLastMode + 1,
+ mode_count_arm
+);
+
+#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;
+}
« no previous file with comments | « src/core/SkXfermode_proccoeff.h ('k') | src/opts/SkXfermode_opts_none.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698