Index: src/opts/SkXfermode_opts.h |
diff --git a/src/opts/SkXfermode_opts.h b/src/opts/SkXfermode_opts.h |
index 7005d593afe698c724336e1bbe58a0d317295f2c..50bef6ac46ae01b6ae1e6fa0062c36b504139966 100644 |
--- a/src/opts/SkXfermode_opts.h |
+++ b/src/opts/SkXfermode_opts.h |
@@ -9,7 +9,7 @@ |
#define Sk4pxXfermode_DEFINED |
#include "Sk4px.h" |
-#include "SkPMFloat.h" |
+#include "SkNx.h" |
#include "SkXfermode_proccoeff.h" |
namespace { |
@@ -110,11 +110,19 @@ XFERMODE(Lighten) { |
#undef XFERMODE |
// Some xfermodes use math like divide or sqrt that's best done in floats 1 pixel at a time. |
-#define XFERMODE(Name) static SkPMFloat SK_VECTORCALL Name(SkPMFloat d, SkPMFloat s) |
+#define XFERMODE(Name) static Sk4f SK_VECTORCALL Name(Sk4f d, Sk4f s) |
+ |
+static inline Sk4f a_rgb(const Sk4f& a, const Sk4f& rgb) { |
+ static_assert(SK_A32_SHIFT == 24, ""); |
+ return a * Sk4f(0,0,0,1) + rgb * Sk4f(1,1,1,0); |
+} |
+static inline Sk4f alphas(const Sk4f& f) { |
+ return Sk4f(f.kth<SK_A32_SHIFT/8>()); |
+} |
XFERMODE(ColorDodge) { |
- auto sa = s.alphas(), |
- da = d.alphas(), |
+ auto sa = alphas(s), |
+ da = alphas(d), |
isa = Sk4f(1)-sa, |
ida = Sk4f(1)-da; |
@@ -126,11 +134,11 @@ XFERMODE(ColorDodge) { |
auto colors = (d == Sk4f(0)).thenElse(dstover, |
(s == sa).thenElse(srcover, |
otherwise)); |
- return srcover * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); |
+ return a_rgb(srcover, colors); |
} |
XFERMODE(ColorBurn) { |
- auto sa = s.alphas(), |
- da = d.alphas(), |
+ auto sa = alphas(s), |
+ da = alphas(d), |
isa = Sk4f(1)-sa, |
ida = Sk4f(1)-da; |
@@ -142,11 +150,11 @@ XFERMODE(ColorBurn) { |
auto colors = (d == da).thenElse(dstover, |
(s == Sk4f(0)).thenElse(srcover, |
otherwise)); |
- return srcover * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); |
+ return a_rgb(srcover, colors); |
} |
XFERMODE(SoftLight) { |
- auto sa = s.alphas(), |
- da = d.alphas(), |
+ auto sa = alphas(s), |
+ da = alphas(d), |
isa = Sk4f(1)-sa, |
ida = Sk4f(1)-da; |
@@ -167,7 +175,7 @@ XFERMODE(SoftLight) { |
auto alpha = s + d*isa; |
auto colors = s*ida + d*isa + (s2 <= sa).thenElse(darkSrc, liteSrc); // Case 1 or 2/3? |
- return alpha * SkPMFloat(1,0,0,0) + colors * SkPMFloat(0,1,1,1); |
+ return a_rgb(alpha, colors); |
} |
#undef XFERMODE |
@@ -232,10 +240,10 @@ private: |
typedef SkProcCoeffXfermode INHERITED; |
}; |
-class SkPMFloatXfermode : public SkProcCoeffXfermode { |
+class Sk4fXfermode : public SkProcCoeffXfermode { |
public: |
- typedef SkPMFloat (SK_VECTORCALL *ProcF)(SkPMFloat, SkPMFloat); |
- SkPMFloatXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, ProcF procf) |
+ typedef Sk4f (SK_VECTORCALL *ProcF)(Sk4f, Sk4f); |
+ Sk4fXfermode(const ProcCoeff& rec, SkXfermode::Mode mode, ProcF procf) |
: INHERITED(rec, mode) |
, fProcF(procf) {} |
@@ -256,18 +264,26 @@ public: |
} |
private: |
+ static Sk4f Load(SkPMColor c) { |
+ return Sk4f::FromBytes((uint8_t*)&c) * Sk4f(1.0f/255); |
+ } |
+ static SkPMColor Round(const Sk4f& f) { |
+ SkPMColor c; |
+ (f * Sk4f(255) + Sk4f(0.5f)).toBytes((uint8_t*)&c); |
+ return c; |
+ } |
inline SkPMColor xfer32(SkPMColor dst, SkPMColor src) const { |
- return fProcF(SkPMFloat(dst), SkPMFloat(src)).round(); |
+ return Round(fProcF(Load(dst), Load(src))); |
} |
inline SkPMColor xfer32(SkPMColor dst, SkPMColor src, SkAlpha aa) const { |
- SkPMFloat s(src), |
- d(dst), |
- b(fProcF(d,s)); |
+ Sk4f s(Load(src)), |
+ d(Load(dst)), |
+ b(fProcF(d,s)); |
// We do aa in full float precision before going back down to bytes, because we can! |
- SkPMFloat a = Sk4f(aa) * Sk4f(1.0f/255); |
+ Sk4f a = Sk4f(aa) * Sk4f(1.0f/255); |
b = b*a + d*(Sk4f(1)-a); |
- return b.round(); |
+ return Round(b); |
} |
ProcF fProcF; |
@@ -280,9 +296,8 @@ namespace SK_OPTS_NS { |
static SkXfermode* create_xfermode(const ProcCoeff& rec, SkXfermode::Mode mode) { |
switch (mode) { |
-#define CASE(Mode) \ |
- case SkXfermode::k##Mode##_Mode: \ |
- return new Sk4pxXfermode(rec, mode, &Mode, &xfer_aa<Mode>) |
+#define CASE(Mode) \ |
+ case SkXfermode::k##Mode##_Mode: return new Sk4pxXfermode(rec, mode, &Mode, &xfer_aa<Mode>) |
CASE(Clear); |
CASE(Src); |
CASE(Dst); |
@@ -307,9 +322,8 @@ static SkXfermode* create_xfermode(const ProcCoeff& rec, SkXfermode::Mode mode) |
CASE(Lighten); |
#undef CASE |
-#define CASE(Mode) \ |
- case SkXfermode::k##Mode##_Mode: \ |
- return new SkPMFloatXfermode(rec, mode, &Mode) |
+#define CASE(Mode) \ |
+ case SkXfermode::k##Mode##_Mode: return new Sk4fXfermode(rec, mode, &Mode) |
CASE(ColorDodge); |
CASE(ColorBurn); |
CASE(SoftLight); |