From 92dabe7421aa6ba4149901108d8ab72956f67eeb Mon Sep 17 00:00:00 2001 From: reed Date: Thu, 2 Apr 2015 19:19:13 -0700 Subject: Exclusion and Difference modes using Sk4f MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before: 7M 1 15.3ms 15.5ms 15.8ms 17.2ms 4% ▁█▄▁▇▂▁▁▂▁ 8888 Xfermode_Exclusion 7M 1 16.5ms 17.1ms 17.3ms 18.8ms 5% ▁█▃█▃▂▂▃▂▂ 8888 Xfermode_Difference After: 7M 1 9.06ms 9.34ms 9.42ms 10.4ms 4% ▁▁▅▄█▁▂▁▂▃ 8888 Xfermode_Exclusion 7M 1 10.5ms 10.9ms 11ms 12ms 5% ▃▁▆█▂▁▅▂▁▃ 8888 Xfermode_Difference TBR=mtklein@google.com Review URL: https://codereview.chromium.org/1060493002 --- src/core/SkXfermode.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'src/core') diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 92743c2fdd..d78dcd8d49 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()); +} + /** * 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 class SkT4fXfermode : public SkProcCoeffXfermode { public: @@ -1445,6 +1480,12 @@ SkXfermode* create_mode(int iMode) { case SkXfermode::kMultiply_Mode: xfer = SkT4fXfermode::Create(rec); break; + case SkXfermode::kDifference_Mode: + xfer = SkT4fXfermode::Create(rec); + break; + case SkXfermode::kExclusion_Mode: + xfer = SkT4fXfermode::Create(rec); + break; default: break; } -- cgit v1.2.3