aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar reed <reed@chromium.org>2015-04-02 19:19:13 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-04-02 19:19:14 -0700
commit92dabe7421aa6ba4149901108d8ab72956f67eeb (patch)
tree39d62f4de1b20a33682fa33d1fcc11e15fdd712c /src/core
parentf8f5478f92d6bce30448203857156a4cda4a13d7 (diff)
Exclusion and Difference modes using Sk4f
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
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkXfermode.cpp41
1 files changed, 41 insertions, 0 deletions
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 <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;
}