Index: src/effects/SkArithmeticMode.cpp |
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp |
index fbe6358ae4ece2550e28d09f76843da41f87dbca..e926f1bc9ad860d98999f732914cf0be03be2225 100644 |
--- a/src/effects/SkArithmeticMode.cpp |
+++ b/src/effects/SkArithmeticMode.cpp |
@@ -7,10 +7,11 @@ |
#include "SkArithmeticMode.h" |
#include "SkColorPriv.h" |
+#include "SkNx.h" |
#include "SkReadBuffer.h" |
-#include "SkWriteBuffer.h" |
#include "SkString.h" |
#include "SkUnPreMultiply.h" |
+#include "SkWriteBuffer.h" |
#if SK_SUPPORT_GPU |
#include "SkArithmeticMode_gpu.h" |
#endif |
@@ -63,64 +64,37 @@ sk_sp<SkFlattenable> SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) { |
return SkArithmeticMode::Make(k1, k2, k3, k4, enforcePMColor); |
} |
-static int pinToByte(int value) { |
- if (value < 0) { |
- value = 0; |
- } else if (value > 255) { |
- value = 255; |
- } |
- return value; |
-} |
+void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], |
+ int count, const SkAlpha aaCoverage[]) const { |
+ const Sk4f k1 = fK[0] * (1/255.0f), |
+ k2 = fK[1], |
+ k3 = fK[2], |
+ k4 = fK[3] * 255.0f + 0.5f; |
+ |
+ auto pin = [](float min, const Sk4f& val, float max) { |
+ return Sk4f::Max(min, Sk4f::Min(val, max)); |
+ }; |
+ |
+ for (int i = 0; i < count; i++) { |
+ if (aaCoverage && aaCoverage[i] == 0) { |
+ continue; |
+ } |
-static int arith(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, |
- int src, int dst) { |
- SkScalar result = SkScalarMul(k1, src * dst) + |
- SkScalarMul(k2, src) + |
- SkScalarMul(k3, dst) + |
- k4; |
- int res = SkScalarRoundToInt(result); |
- return pinToByte(res); |
-} |
+ Sk4f s = SkNx_cast<float>(Sk4b::Load(src+i)), |
+ d = SkNx_cast<float>(Sk4b::Load(dst+i)), |
+ r = pin(0, k1*s*d + k2*s + k3*d + k4, 255); |
-static int blend(int src, int dst, int scale) { |
- return dst + ((src - dst) * scale >> 8); |
-} |
+ if (fEnforcePMColor) { |
+ Sk4f a = SkNx_shuffle<3,3,3,3>(r); |
+ r = Sk4f::Min(a, r); |
+ } |
-void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], |
- int count, const SkAlpha aaCoverage[]) const { |
- SkScalar k1 = fK[0] / 255; |
- SkScalar k2 = fK[1]; |
- SkScalar k3 = fK[2]; |
- SkScalar k4 = fK[3] * 255; |
- |
- for (int i = 0; i < count; ++i) { |
- if ((nullptr == aaCoverage) || aaCoverage[i]) { |
- SkPMColor sc = src[i]; |
- SkPMColor dc = dst[i]; |
- |
- int a, r, g, b; |
- |
- a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc)); |
- r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)); |
- g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)); |
- b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)); |
- if (fEnforcePMColor) { |
- r = SkMin32(r, a); |
- g = SkMin32(g, a); |
- b = SkMin32(b, a); |
- } |
- |
- // apply antialias coverage if necessary |
- if (aaCoverage && 0xFF != aaCoverage[i]) { |
- int scale = aaCoverage[i] + (aaCoverage[i] >> 7); |
- a = blend(a, SkGetPackedA32(sc), scale); |
- r = blend(r, SkGetPackedR32(sc), scale); |
- g = blend(g, SkGetPackedG32(sc), scale); |
- b = blend(b, SkGetPackedB32(sc), scale); |
- } |
- |
- dst[i] = fEnforcePMColor ? SkPackARGB32(a, r, g, b) : SkPackARGB32NoCheck(a, r, g, b); |
+ if (aaCoverage && aaCoverage[i] != 255) { |
+ Sk4f c = aaCoverage[i] * (1/255.0f); |
+ r = d + (r-d)*c; |
} |
+ |
+ SkNx_cast<uint8_t>(r).store(dst+i); |
} |
} |