aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar reed <reed@chromium.org>2015-04-02 17:13:21 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-04-02 17:13:22 -0700
commitf8f5478f92d6bce30448203857156a4cda4a13d7 (patch)
tree8db4097ed812dff2250449abe2f119543cfe61e7 /src
parentfb806dd27d93d09a1aedac6c4666f4424c7d9c7d (diff)
impl Multiply mode using Sk4f
Before: 7M 1 14.4ms 14.8ms 15.4ms 17.5ms 7% ▆█▅▅▂▁▁▁▂▁ 8888 Xfermode_Multiply After: 7M 1 12ms 12.1ms 12.5ms 14.1ms 6% ▃█▇▂▁▂▁▁▂▁ 8888 Xfermode_Multiply TBR=mtklein@google.com Review URL: https://codereview.chromium.org/1056003002
Diffstat (limited to 'src')
-rw-r--r--src/core/SkXfermode.cpp26
1 files changed, 24 insertions, 2 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 2aaef70fb9..92743c2fdd 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -1194,7 +1194,11 @@ static Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) {
}
static Sk4f clamp_255(const Sk4f& value) {
- return Sk4f::Min(value, Sk4f(255));
+ return Sk4f::Min(Sk4f(255), value);
+}
+
+static Sk4f clamp_0_255(const Sk4f& value) {
+ return Sk4f::Max(Sk4f(0), Sk4f::Min(Sk4f(255), value));
}
/**
@@ -1286,12 +1290,27 @@ struct Screen4f {
const Sk4f inv255(gInv255);
Sk4f s4 = src;
Sk4f d4 = dst;
- return check_as_pmfloat(check_as_pmfloat(s4 + d4 - s4 * d4 * inv255));
+ return check_as_pmfloat(s4 + d4 - s4 * d4 * inv255);
}
static const bool kFoldCoverageIntoSrcAlpha = true;
static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode;
};
+struct Multiply4f {
+ 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 rc = sc + dc + (sc * (dc - da) - dc * sa) * inv255;
+ // ra = srcover(sa, da), but the calc for rc happens to accomplish this for us
+ return check_as_pmfloat(clamp_0_255(rc));
+ }
+ static const bool kFoldCoverageIntoSrcAlpha = false;
+ static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode;
+};
+
template <typename ProcType>
class SkT4fXfermode : public SkProcCoeffXfermode {
public:
@@ -1423,6 +1442,9 @@ SkXfermode* create_mode(int iMode) {
case SkXfermode::kScreen_Mode:
xfer = SkT4fXfermode<Screen4f>::Create(rec);
break;
+ case SkXfermode::kMultiply_Mode:
+ xfer = SkT4fXfermode<Multiply4f>::Create(rec);
+ break;
default:
break;
}