Index: src/core/SkXfermodeU64.cpp |
diff --git a/src/core/SkXfermodeU64.cpp b/src/core/SkXfermodeU64.cpp |
index 5d260c171349a8f4f9b84fafe97d06164c5ddffa..2609f89a2f13d059018ae0e5fe99027fa21ee14a 100644 |
--- a/src/core/SkXfermodeU64.cpp |
+++ b/src/core/SkXfermodeU64.cpp |
@@ -16,11 +16,6 @@ static void sk_memset64(uint64_t dst[], uint64_t value, int count) { |
} |
} |
-struct U64ProcPair { |
- SkXfermode::U64Proc1 fP1; |
- SkXfermode::U64ProcN fPN; |
-}; |
- |
enum DstType { |
kU16_Dst, |
kF16_Dst, |
@@ -72,29 +67,29 @@ static inline Sk4f pm_to_rgba_order(const Sk4f& x) { |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
-template <DstType D> void xfer_u64_1(const SkXfermode::U64State& state, uint64_t dst[], |
- const SkPM4f& src, int count, const SkAlpha aa[]) { |
- SkXfermodeProc4f proc = state.fXfer->getProc4f(); |
+template <DstType D> void xfer_u64_1(const SkXfermode* xfer, uint64_t dst[], |
+ const SkPM4f* src, int count, const SkAlpha aa[]) { |
+ SkXfermodeProc4f proc = xfer->getProc4f(); |
SkPM4f d; |
if (aa) { |
for (int i = 0; i < count; ++i) { |
Sk4f d4 = bias_to_unit<D>(load_from_dst<D>(dst[i])); |
d4.store(d.fVec); |
- Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src, d).fVec)); |
+ Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(*src, d).fVec)); |
dst[i] = store_to_dst<D>(lerp_by_coverage(r4, d4, aa[i])); |
} |
} else { |
for (int i = 0; i < count; ++i) { |
bias_to_unit<D>(load_from_dst<D>(dst[i])).store(d.fVec); |
- Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src, d).fVec)); |
+ Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(*src, d).fVec)); |
dst[i] = store_to_dst<D>(r4); |
} |
} |
} |
-template <DstType D> void xfer_u64_n(const SkXfermode::U64State& state, uint64_t dst[], |
+template <DstType D> void xfer_u64_n(const SkXfermode* xfer, uint64_t dst[], |
const SkPM4f src[], int count, const SkAlpha aa[]) { |
- SkXfermodeProc4f proc = state.fXfer->getProc4f(); |
+ SkXfermodeProc4f proc = xfer->getProc4f(); |
SkPM4f d; |
if (aa) { |
for (int i = 0; i < count; ++i) { |
@@ -112,18 +107,41 @@ template <DstType D> void xfer_u64_n(const SkXfermode::U64State& state, uint64_t |
} |
} |
-const U64ProcPair gU64Procs_General[] = { |
- { xfer_u64_1<kU16_Dst>, xfer_u64_n<kU16_Dst> }, // U16 alpha |
- { xfer_u64_1<kU16_Dst>, xfer_u64_n<kU16_Dst> }, // U16 opaque |
- { xfer_u64_1<kF16_Dst>, xfer_u64_n<kF16_Dst> }, // F16 alpha |
- { xfer_u64_1<kF16_Dst>, xfer_u64_n<kF16_Dst> }, // F16 opaque |
+const SkXfermode::D64Proc gProcs_General[] = { |
+ xfer_u64_n<kU16_Dst>, xfer_u64_n<kU16_Dst>, |
+ xfer_u64_1<kU16_Dst>, xfer_u64_1<kU16_Dst>, |
+ xfer_u64_n<kF16_Dst>, xfer_u64_n<kF16_Dst>, |
+ xfer_u64_1<kF16_Dst>, xfer_u64_1<kF16_Dst>, |
}; |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
-template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[], |
- const SkPM4f& src, int count, const SkAlpha aa[]) { |
- const Sk4f s4 = pm_to_rgba_order(unit_to_bias<D>(Sk4f::Load(src.fVec))); |
+template <DstType D> void clear(const SkXfermode*, uint64_t dst[], |
+ const SkPM4f*, int count, const SkAlpha aa[]) { |
+ if (aa) { |
+ for (int i = 0; i < count; ++i) { |
+ if (aa[i]) { |
+ const Sk4f d4 = load_from_dst<D>(dst[i]); |
+ dst[i] = store_to_dst<D>(d4 * Sk4f((255 - aa[i]) * 1.0f/255)); |
+ } |
+ } |
+ } else { |
+ sk_memset64(dst, 0, count); |
+ } |
+} |
+ |
+const SkXfermode::D64Proc gProcs_Clear[] = { |
+ clear<kU16_Dst>, clear<kU16_Dst>, |
+ clear<kU16_Dst>, clear<kU16_Dst>, |
+ clear<kF16_Dst>, clear<kF16_Dst>, |
+ clear<kF16_Dst>, clear<kF16_Dst>, |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+template <DstType D> void src_1(const SkXfermode*, uint64_t dst[], |
+ const SkPM4f* src, int count, const SkAlpha aa[]) { |
+ const Sk4f s4 = pm_to_rgba_order(unit_to_bias<D>(Sk4f::Load(src->fVec))); |
if (aa) { |
for (int i = 0; i < count; ++i) { |
const Sk4f d4 = load_from_dst<D>(dst[i]); |
@@ -134,7 +152,7 @@ template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[ |
} |
} |
-template <DstType D> void src_n(const SkXfermode::U64State& state, uint64_t dst[], |
+template <DstType D> void src_n(const SkXfermode*, uint64_t dst[], |
const SkPM4f src[], int count, const SkAlpha aa[]) { |
if (aa) { |
for (int i = 0; i < count; ++i) { |
@@ -150,18 +168,26 @@ template <DstType D> void src_n(const SkXfermode::U64State& state, uint64_t dst[ |
} |
} |
-const U64ProcPair gU64Procs_Src[] = { |
- { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 alpha |
- { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 opaque |
- { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 alpha |
- { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 opaque |
+const SkXfermode::D64Proc gProcs_Src[] = { |
+ src_n<kU16_Dst>, src_n<kU16_Dst>, |
+ src_1<kU16_Dst>, src_1<kU16_Dst>, |
+ src_n<kF16_Dst>, src_n<kF16_Dst>, |
+ src_1<kF16_Dst>, src_1<kF16_Dst>, |
}; |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
-template <DstType D> void srcover_1(const SkXfermode::U64State& state, uint64_t dst[], |
- const SkPM4f& src, int count, const SkAlpha aa[]) { |
- const Sk4f s4 = pm_to_rgba_order(Sk4f::Load(src.fVec)); |
+static void dst(const SkXfermode*, uint64_t*, const SkPM4f*, int count, const SkAlpha[]) {} |
+ |
+const SkXfermode::D64Proc gProcs_Dst[] = { |
+ dst, dst, dst, dst, dst, dst, dst, dst, |
+}; |
+ |
+/////////////////////////////////////////////////////////////////////////////////////////////////// |
+ |
+template <DstType D> void srcover_1(const SkXfermode*, uint64_t dst[], |
+ const SkPM4f* src, int count, const SkAlpha aa[]) { |
+ const Sk4f s4 = pm_to_rgba_order(Sk4f::Load(src->fVec)); |
const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); |
const Sk4f s4bias = unit_to_bias<D>(s4); |
for (int i = 0; i < count; ++i) { |
@@ -175,7 +201,7 @@ template <DstType D> void srcover_1(const SkXfermode::U64State& state, uint64_t |
} |
} |
-template <DstType D> void srcover_n(const SkXfermode::U64State& state, uint64_t dst[], |
+template <DstType D> void srcover_n(const SkXfermode*, uint64_t dst[], |
const SkPM4f src[], int count, const SkAlpha aa[]) { |
for (int i = 0; i < count; ++i) { |
const Sk4f s4 = pm_to_rgba_order(Sk4f::Load(src[i].fVec)); |
@@ -191,32 +217,39 @@ template <DstType D> void srcover_n(const SkXfermode::U64State& state, uint64_t |
} |
} |
-const U64ProcPair gU64Procs_SrcOver[] = { |
- { srcover_1<kU16_Dst>, srcover_n<kU16_Dst> }, // U16 alpha |
- { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 opaque |
- { srcover_1<kF16_Dst>, srcover_n<kF16_Dst> }, // F16 alpha |
- { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 opaque |
+const SkXfermode::D64Proc gProcs_SrcOver[] = { |
+ srcover_n<kU16_Dst>, src_n<kU16_Dst>, |
+ srcover_1<kU16_Dst>, src_1<kU16_Dst>, |
+ srcover_n<kF16_Dst>, src_n<kF16_Dst>, |
+ srcover_1<kF16_Dst>, src_1<kF16_Dst>, |
}; |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
-static U64ProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) { |
- SkASSERT(0 == (flags & ~3)); |
- flags &= 3; |
+static SkXfermode::D64Proc find_proc(SkXfermode::Mode mode, uint32_t flags) { |
+ SkASSERT(0 == (flags & ~7)); |
+ flags &= 7; |
switch (mode) { |
- case SkXfermode::kSrc_Mode: return gU64Procs_Src[flags]; |
- case SkXfermode::kSrcOver_Mode: return gU64Procs_SrcOver[flags]; |
+ case SkXfermode::kClear_Mode: return gProcs_Clear[flags]; |
+ case SkXfermode::kSrc_Mode: return gProcs_Src[flags]; |
+ case SkXfermode::kDst_Mode: return gProcs_Dst[flags]; |
+ case SkXfermode::kSrcOver_Mode: return gProcs_SrcOver[flags]; |
default: |
break; |
} |
- return gU64Procs_General[flags]; |
+ return gProcs_General[flags]; |
} |
-SkXfermode::U64Proc1 SkXfermode::GetU64Proc1(Mode mode, uint32_t flags) { |
- return find_procs(mode, flags).fP1; |
+SkXfermode::D64Proc SkXfermode::onGetD64Proc(uint32_t flags) const { |
+ SkASSERT(0 == (flags & ~7)); |
+ flags &= 7; |
+ |
+ Mode mode; |
+ return this->asMode(&mode) ? find_proc(mode, flags) : gProcs_General[flags]; |
} |
-SkXfermode::U64ProcN SkXfermode::GetU64ProcN(Mode mode, uint32_t flags) { |
- return find_procs(mode, flags).fPN; |
+SkXfermode::D64Proc SkXfermode::GetD64Proc(SkXfermode* xfer, uint32_t flags) { |
+ return xfer ? xfer->onGetD64Proc(flags) : find_proc(SkXfermode::kSrcOver_Mode, flags); |
} |
+ |