Chromium Code Reviews| Index: src/core/SkXfermode.cpp |
| diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp |
| index 92743c2fddeddd86d62dc9df14f358c5ee22cdc4..d78dcd8d4932041a28ec9c19575feff4c83daadf 100644 |
| --- a/src/core/SkXfermode.cpp |
| +++ b/src/core/SkXfermode.cpp |
| @@ -1201,6 +1201,13 @@ static Sk4f clamp_0_255(const Sk4f& value) { |
| return Sk4f::Max(Sk4f(0), Sk4f::Min(Sk4f(255), value)); |
| } |
| +// return a swizzle of a | rgb |
| +static Sk4f set_a_rgb(const Sk4f& a, const Sk4f& rgb) { |
| + SkPMFloat pma = a; |
| + SkPMFloat pmc = rgb; |
| + return SkPMFloat(pma.a(), pmc.r(), pmc.g(), pmc.b()); |
|
mtklein
2015/04/03 13:23:58
Boy, this is annoying. We can make this operation
mtklein
2015/04/03 13:35:47
Well, maybe it's not so annoying. On x86 this can
|
| +} |
| + |
| /** |
| * Some modes can, due to very slight numerical error, generate "invalid" pmcolors... |
| * |
| @@ -1311,6 +1318,34 @@ struct Multiply4f { |
| static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; |
| }; |
| +struct Difference4f { |
| + static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| + const Sk4f inv255(gInv255); |
| + Sk4f sa = Sk4f(src.a()); |
| + Sk4f da = Sk4f(dst.a()); |
| + Sk4f sc = src; |
| + Sk4f dc = dst; |
| + Sk4f min = Sk4f::Min(sc * da, dc * sa) * inv255; |
| + Sk4f ra = sc + dc - min; |
| + return check_as_pmfloat(set_a_rgb(ra, ra - min)); |
| + } |
| + static const bool kFoldCoverageIntoSrcAlpha = false; |
| + static const SkXfermode::Mode kMode = SkXfermode::kDifference_Mode; |
| +}; |
| + |
| +struct Exclusion4f { |
| + static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| + const Sk4f inv255(gInv255); |
| + Sk4f sc = src; |
| + Sk4f dc = dst; |
| + Sk4f prod = sc * dc * inv255; |
| + Sk4f ra = sc + dc - prod; |
| + return check_as_pmfloat(set_a_rgb(ra, ra - prod)); |
| + } |
| + static const bool kFoldCoverageIntoSrcAlpha = false; |
| + static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; |
| +}; |
| + |
| template <typename ProcType> |
| class SkT4fXfermode : public SkProcCoeffXfermode { |
| public: |
| @@ -1445,6 +1480,12 @@ SkXfermode* create_mode(int iMode) { |
| case SkXfermode::kMultiply_Mode: |
| xfer = SkT4fXfermode<Multiply4f>::Create(rec); |
| break; |
| + case SkXfermode::kDifference_Mode: |
| + xfer = SkT4fXfermode<Difference4f>::Create(rec); |
| + break; |
| + case SkXfermode::kExclusion_Mode: |
| + xfer = SkT4fXfermode<Exclusion4f>::Create(rec); |
| + break; |
| default: |
| break; |
| } |