Chromium Code Reviews| Index: src/core/SkXfermodeU64.cpp |
| diff --git a/src/core/SkXfermodeU64.cpp b/src/core/SkXfermodeU64.cpp |
| index 6435e6a2e2b0aa170e8a6fb5502283a9e13f8fa1..aed9ce09cb04bad3265e0169bbc382f180bb79ea 100644 |
| --- a/src/core/SkXfermodeU64.cpp |
| +++ b/src/core/SkXfermodeU64.cpp |
| @@ -30,10 +30,14 @@ static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCovera |
| return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); |
| } |
| -template <DstType D> Sk4f unit_to_dst_bias(const Sk4f& x4) { |
| +template <DstType D> Sk4f unit_to_bias(const Sk4f& x4) { |
| return (D == kU16_Dst) ? x4 * Sk4f(65535) : x4; |
| } |
| +template <DstType D> Sk4f bias_to_unit(const Sk4f& x4) { |
| + return (D == kU16_Dst) ? x4 * Sk4f(1.0f/65535) : x4; |
| +} |
| + |
| // returns value already biased by 65535 |
| static Sk4f load_from_u16(uint64_t value) { |
| return SkNx_cast<float>(Sk4h::Load(&value)); |
| @@ -80,9 +84,58 @@ template <DstType D> uint64_t store_to_dst(const Sk4f& x4) { |
| /////////////////////////////////////////////////////////////////////////////////////////////////// |
| +template <DstType D> void src_u64_1(const SkXfermode::U64State& state, uint64_t dst[], |
|
mtklein
2016/02/10 16:19:34
why is this called src_u64_1? It's not always src
|
| + const SkPM4f& src, int count, const SkAlpha aa[]) { |
| + SkXfermodeProc4f proc = state.fXfer->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); |
|
mtklein
2016/02/10 16:19:34
Do these stores and loads disappear? Seems like t
|
| + 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)); |
| + dst[i] = store_to_dst<D>(r4); |
| + } |
| + } |
| +} |
| + |
| +template <DstType D> void xfer_u64_n(const SkXfermode::U64State& state, uint64_t dst[], |
| + const SkPM4f src[], int count, const SkAlpha aa[]) { |
| + SkXfermodeProc4f proc = state.fXfer->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[i], 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[i], d).fVec)); |
| + dst[i] = store_to_dst<D>(r4); |
| + } |
| + } |
| +} |
| + |
| +const U64ProcPair gU64Procs_General[] = { |
| + { src_u64_1<kU16_Dst>, xfer_u64_n<kU16_Dst> }, // U16 alpha |
| + { src_u64_1<kU16_Dst>, xfer_u64_n<kU16_Dst> }, // U16 opaque |
| + { src_u64_1<kF16_Dst>, xfer_u64_n<kF16_Dst> }, // F16 alpha |
| + { src_u64_1<kF16_Dst>, xfer_u64_n<kF16_Dst> }, // F16 opaque |
| +}; |
| + |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[], |
| const SkPM4f& src, int count, const SkAlpha aa[]) { |
| - const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src.fVec)); |
| + const Sk4f s4 = 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]); |
| @@ -97,13 +150,13 @@ template <DstType D> void src_n(const SkXfermode::U64State& state, uint64_t dst[ |
| const SkPM4f src[], int count, const SkAlpha aa[]) { |
| if (aa) { |
| for (int i = 0; i < count; ++i) { |
| - const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src[i].fVec)); |
| + const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src[i].fVec)); |
| const Sk4f d4 = load_from_dst<D>(dst[i]); |
| dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); |
| } |
| } else { |
| for (int i = 0; i < count; ++i) { |
| - const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src[i].fVec)); |
| + const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src[i].fVec)); |
| dst[i] = store_to_dst<D>(s4); |
| } |
| } |
| @@ -122,7 +175,7 @@ template <DstType D> void srcover_1(const SkXfermode::U64State& state, uint64_t |
| const SkPM4f& src, int count, const SkAlpha aa[]) { |
| const Sk4f s4 = Sk4f::Load(src.fVec); |
| const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); |
| - const Sk4f s4bias = unit_to_dst_bias<D>(s4); |
| + const Sk4f s4bias = unit_to_bias<D>(s4); |
| for (int i = 0; i < count; ++i) { |
| const Sk4f d4bias = load_from_dst<D>(dst[i]); |
| const Sk4f r4bias = s4bias + d4bias * dst_scale; |
| @@ -139,7 +192,7 @@ template <DstType D> void srcover_n(const SkXfermode::U64State& state, uint64_t |
| for (int i = 0; i < count; ++i) { |
| const Sk4f s4 = Sk4f::Load(src[i].fVec); |
| const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); |
| - const Sk4f s4bias = unit_to_dst_bias<D>(s4); |
| + const Sk4f s4bias = unit_to_bias<D>(s4); |
| const Sk4f d4bias = load_from_dst<D>(dst[i]); |
| const Sk4f r4bias = s4bias + d4bias * dst_scale; |
| if (aa) { |
| @@ -169,7 +222,7 @@ static U64ProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) { |
| default: |
| break; |
| } |
| - return { nullptr, nullptr }; |
| + return gU64Procs_General[flags]; |
| } |
| SkXfermode::U64Proc1 SkXfermode::GetU64Proc1(Mode mode, uint32_t flags) { |