aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar mtklein <mtklein@chromium.org>2015-05-21 15:47:40 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-21 15:47:40 -0700
commit160d08cb01a395e584a767b00f45e7fcf996b890 (patch)
tree443763fa93e3d667b0c16c94c6d7254e6b35d9eb
parent5a72c4295263a59c74acb119e405b5e5ac2df70f (diff)
Fix Plus
This makes Plus with AA ~3% slower. Seems like a good deal. GMs affected: mixed_xfermodes, the new one. Based on https://codereview.chromium.org/1150833003/ Still TODO: NEON. The new GM should show this. BUG=skia:3852 Review URL: https://codereview.chromium.org/1156453002
-rw-r--r--src/core/SkXfermode.cpp28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 928fa5001e..99f83f9f3d 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1241,6 +1241,30 @@ XFERMODE(Exclusion) {
#undef XFERMODE
+// A reasonable fallback mode for doing AA is to simply apply the transfermode first,
+// then linearly interpolate the AA.
+template <typename Mode>
+static Sk4px xfer_aa(const Sk4px& s, const Sk4px& d, const Sk16b& aa) {
+ Sk4px noAA = Mode::Xfer(s, d);
+ return Sk4px::Wide(noAA.mulWiden(aa) + d.mulWiden(Sk4px(aa).inv()))
+ .div255RoundNarrow();
+}
+
+// For some transfermodes we specialize AA, either for correctness or performance.
+#ifndef SK_NO_SPECIALIZED_AA_XFERMODES
+ #define XFERMODE_AA(Name) \
+ template <> Sk4px xfer_aa<Name>(const Sk4px& s, const Sk4px& d, const Sk16b& aa)
+
+ // Plus' clamp needs to happen after AA. skia:3852
+ XFERMODE_AA(Plus) { // [ clamp(D + AA*S) ]
+ // We implement this as D + Min(S*AA, (1-D)) to fit the arguments to Min in 16 bits.
+ return d +
+ Sk4px::Wide(Sk16h::Min(s.mulWiden(aa), d.inv().mul255Widen())).div255RoundNarrow();
+ }
+
+ #undef XFERMODE_AA
+#endif
+
template <typename ProcType>
class SkT4pxXfermode : public SkProcCoeffXfermode {
public:
@@ -1256,9 +1280,7 @@ public:
} else {
Sk4px::MapDstSrcAlpha(n, dst, src, aa,
[&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha) {
- Sk4px res4 = ProcType::Xfer(src4, dst4);
- return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk4px(alpha).inv()))
- .div255RoundNarrow();
+ return xfer_aa<ProcType>(src4, dst4, alpha);
});
}
}