Chromium Code Reviews| Index: src/core/SkXfermode.cpp |
| diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp |
| index 7165e99161bd2bc69e4aff56e536a1c5f9e5d336..9c68e3f7a459d6f188d9e1055efb03be49e761f7 100644 |
| --- a/src/core/SkXfermode.cpp |
| +++ b/src/core/SkXfermode.cpp |
| @@ -12,6 +12,7 @@ |
| #include "SkColorPriv.h" |
| #include "SkLazyPtr.h" |
| #include "SkMathPriv.h" |
| +#include "SkPMFloat.h" |
| #include "SkReadBuffer.h" |
| #include "SkString.h" |
| #include "SkUtilsArm.h" |
| @@ -1186,6 +1187,66 @@ void SkDstInXfermode::toString(SkString* str) const { |
| /////////////////////////////////////////////////////////////////////////////// |
| +static const float gInv255 = 0.0039215683f; // (1.0f / 255) - ULP == SkBits2Float(0x3B808080) |
| + |
| +static Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) { |
| + return v0 + (v1 - v0) * t; |
| +} |
| + |
| +// kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc] |
|
mtklein
2015/04/01 19:33:55
I suspect that this formulation of src-atop has tr
|
| +static inline SkPMFloat srcatop(const SkPMFloat& src, const SkPMFloat& dst) { |
| + const Sk4f inv255(gInv255); |
| + Sk4f s4 = src; |
| + Sk4f d4 = dst; |
| + SkPMFloat res = d4 + (s4 * Sk4f(dst.a()) - d4 * Sk4f(src.a())) * inv255; |
| + SkPMFloat res2 = SkPMFloat::FromARGB(dst.a(), res.r(), res.g(), res.b()); |
| + SkASSERT(res2.isValid()); |
| + return res2; |
| +} |
| + |
| +class SkSrcATopXfermode : public SkProcCoeffXfermode { |
| +public: |
| + static SkXfermode* Create(const ProcCoeff& rec) { |
| + return SkNEW_ARGS(SkSrcATopXfermode, (rec)); |
| + } |
| + |
| + void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[]) const override { |
| + if (NULL == aa) { |
| + while (n & 3) { |
| + *dst = srcatop(SkPMFloat(*src++), SkPMFloat(*dst)).get(); |
| + dst++; |
| + n -= 1; |
| + } |
| + n >>= 2; |
| + for (int i = 0; i < n; ++i) { |
| + SkPMFloat s0, s1, s2, s3; |
| + SkPMFloat::From4PMColors(src, &s0, &s1, &s2, &s3); |
| + SkPMFloat d0, d1, d2, d3; |
| + SkPMFloat::From4PMColors(dst, &d0, &d1, &d2, &d3); |
| + SkPMFloat::To4PMColors(srcatop(s0, d0), srcatop(s1, d1), |
| + srcatop(s2, d2), srcatop(s3, d3), dst); |
| + src += 4; |
| + dst += 4; |
| + } |
| + } else { |
| + for (int i = 0; i < n; ++i) { |
| + SkPMFloat dstF(dst[i]); |
| + SkPMFloat resF = srcatop(SkPMFloat(src[i]), dstF); |
| + dst[i] = SkPMFloat(ramp(dstF, resF, Sk4f(aa[i] * gInv255))).get(); |
| + } |
| + } |
| + } |
| + |
| +// SK_TO_STRING_OVERRIDE() |
| + |
| +private: |
| + SkSrcATopXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrcATop_Mode) {} |
| + |
| + typedef SkProcCoeffXfermode INHERITED; |
| +}; |
| + |
| +/////////////////////////////////////////////////////////////////////////////// |
| + |
| class SkDstOutXfermode : public SkProcCoeffXfermode { |
| public: |
| static SkDstOutXfermode* Create(const ProcCoeff& rec) { |
| @@ -1247,6 +1308,9 @@ SkXfermode* create_mode(int iMode) { |
| SkXfermode* xfer = NULL; |
| // check if we have a platform optim for that |
| SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); |
| +#if 1 |
| + xfm = NULL; |
| +#endif |
| if (xfm != NULL) { |
| xfer = xfm; |
| } else { |
| @@ -1269,6 +1333,9 @@ SkXfermode* create_mode(int iMode) { |
| case SkXfermode::kDstOut_Mode: |
| xfer = SkDstOutXfermode::Create(rec); |
| break; |
| + case SkXfermode::kSrcATop_Mode: |
| + xfer = SkSrcATopXfermode::Create(rec); |
| + break; |
| default: |
| // no special-case, just rely in the rec and its function-ptrs |
| xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); |