Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkHalf.h" | 8 #include "SkHalf.h" |
| 9 #include "SkPM4fPriv.h" | 9 #include "SkPM4fPriv.h" |
| 10 #include "SkUtils.h" | 10 #include "SkUtils.h" |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 | 23 |
| 24 enum DstType { | 24 enum DstType { |
| 25 kU16_Dst, | 25 kU16_Dst, |
| 26 kF16_Dst, | 26 kF16_Dst, |
| 27 }; | 27 }; |
| 28 | 28 |
| 29 static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCovera ge) { | 29 static Sk4f lerp_by_coverage(const Sk4f& src, const Sk4f& dst, uint8_t srcCovera ge) { |
| 30 return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); | 30 return dst + (src - dst) * Sk4f(srcCoverage * (1/255.0f)); |
| 31 } | 31 } |
| 32 | 32 |
| 33 template <DstType D> Sk4f unit_to_dst_bias(const Sk4f& x4) { | 33 template <DstType D> Sk4f unit_to_bias(const Sk4f& x4) { |
| 34 return (D == kU16_Dst) ? x4 * Sk4f(65535) : x4; | 34 return (D == kU16_Dst) ? x4 * Sk4f(65535) : x4; |
| 35 } | 35 } |
| 36 | 36 |
| 37 template <DstType D> Sk4f bias_to_unit(const Sk4f& x4) { | |
| 38 return (D == kU16_Dst) ? x4 * Sk4f(1.0f/65535) : x4; | |
| 39 } | |
| 40 | |
| 37 // returns value already biased by 65535 | 41 // returns value already biased by 65535 |
| 38 static Sk4f load_from_u16(uint64_t value) { | 42 static Sk4f load_from_u16(uint64_t value) { |
| 39 return SkNx_cast<float>(Sk4h::Load(&value)); | 43 return SkNx_cast<float>(Sk4h::Load(&value)); |
| 40 } | 44 } |
| 41 | 45 |
| 42 // takes floats already biased by 65535 | 46 // takes floats already biased by 65535 |
| 43 static uint64_t store_to_u16(const Sk4f& x4) { | 47 static uint64_t store_to_u16(const Sk4f& x4) { |
| 44 uint64_t value; | 48 uint64_t value; |
| 45 SkNx_cast<uint16_t>(x4 + Sk4f(0.5f)).store(&value); | 49 SkNx_cast<uint16_t>(x4 + Sk4f(0.5f)).store(&value); |
| 46 return value; | 50 return value; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 73 return (D == kU16_Dst) ? load_from_u16(dst) : load_from_f16(dst); | 77 return (D == kU16_Dst) ? load_from_u16(dst) : load_from_f16(dst); |
| 74 } | 78 } |
| 75 | 79 |
| 76 // Assumes x4 is already in the "natural" bias (either unit-float or 16bit int) | 80 // Assumes x4 is already in the "natural" bias (either unit-float or 16bit int) |
| 77 template <DstType D> uint64_t store_to_dst(const Sk4f& x4) { | 81 template <DstType D> uint64_t store_to_dst(const Sk4f& x4) { |
| 78 return (D == kU16_Dst) ? store_to_u16(x4) : store_to_f16(x4); | 82 return (D == kU16_Dst) ? store_to_u16(x4) : store_to_f16(x4); |
| 79 } | 83 } |
| 80 | 84 |
| 81 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 85 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 82 | 86 |
| 87 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
| |
| 88 const SkPM4f& src, int count, const SkAlpha aa[]) { | |
| 89 SkXfermodeProc4f proc = state.fXfer->getProc4f(); | |
| 90 SkPM4f d; | |
| 91 if (aa) { | |
| 92 for (int i = 0; i < count; ++i) { | |
| 93 Sk4f d4 = bias_to_unit<D>(load_from_dst<D>(dst[i])); | |
| 94 d4.store(d.fVec); | |
|
mtklein
2016/02/10 16:19:34
Do these stores and loads disappear? Seems like t
| |
| 95 Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src, d).fVec)); | |
| 96 dst[i] = store_to_dst<D>(lerp_by_coverage(r4, d4, aa[i])); | |
| 97 } | |
| 98 } else { | |
| 99 for (int i = 0; i < count; ++i) { | |
| 100 bias_to_unit<D>(load_from_dst<D>(dst[i])).store(d.fVec); | |
| 101 Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src, d).fVec)); | |
| 102 dst[i] = store_to_dst<D>(r4); | |
| 103 } | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 template <DstType D> void xfer_u64_n(const SkXfermode::U64State& state, uint64_t dst[], | |
| 108 const SkPM4f src[], int count, const SkAlph a aa[]) { | |
| 109 SkXfermodeProc4f proc = state.fXfer->getProc4f(); | |
| 110 SkPM4f d; | |
| 111 if (aa) { | |
| 112 for (int i = 0; i < count; ++i) { | |
| 113 Sk4f d4 = bias_to_unit<D>(load_from_dst<D>(dst[i])); | |
| 114 d4.store(d.fVec); | |
| 115 Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src[i], d).fVec)); | |
| 116 dst[i] = store_to_dst<D>(lerp_by_coverage(r4, d4, aa[i])); | |
| 117 } | |
| 118 } else { | |
| 119 for (int i = 0; i < count; ++i) { | |
| 120 bias_to_unit<D>(load_from_dst<D>(dst[i])).store(d.fVec); | |
| 121 Sk4f r4 = unit_to_bias<D>(Sk4f::Load(proc(src[i], d).fVec)); | |
| 122 dst[i] = store_to_dst<D>(r4); | |
| 123 } | |
| 124 } | |
| 125 } | |
| 126 | |
| 127 const U64ProcPair gU64Procs_General[] = { | |
| 128 { src_u64_1<kU16_Dst>, xfer_u64_n<kU16_Dst> }, // U16 alpha | |
| 129 { src_u64_1<kU16_Dst>, xfer_u64_n<kU16_Dst> }, // U16 opaque | |
| 130 { src_u64_1<kF16_Dst>, xfer_u64_n<kF16_Dst> }, // F16 alpha | |
| 131 { src_u64_1<kF16_Dst>, xfer_u64_n<kF16_Dst> }, // F16 opaque | |
| 132 }; | |
| 133 | |
| 134 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
| 135 | |
| 83 template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[ ], | 136 template <DstType D> void src_1(const SkXfermode::U64State& state, uint64_t dst[ ], |
| 84 const SkPM4f& src, int count, const SkAlpha aa[] ) { | 137 const SkPM4f& src, int count, const SkAlpha aa[] ) { |
| 85 const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src.fVec)); | 138 const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src.fVec)); |
| 86 if (aa) { | 139 if (aa) { |
| 87 for (int i = 0; i < count; ++i) { | 140 for (int i = 0; i < count; ++i) { |
| 88 const Sk4f d4 = load_from_dst<D>(dst[i]); | 141 const Sk4f d4 = load_from_dst<D>(dst[i]); |
| 89 dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); | 142 dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); |
| 90 } | 143 } |
| 91 } else { | 144 } else { |
| 92 sk_memset64(dst, store_to_dst<D>(s4), count); | 145 sk_memset64(dst, store_to_dst<D>(s4), count); |
| 93 } | 146 } |
| 94 } | 147 } |
| 95 | 148 |
| 96 template <DstType D> void src_n(const SkXfermode::U64State& state, uint64_t dst[ ], | 149 template <DstType D> void src_n(const SkXfermode::U64State& state, uint64_t dst[ ], |
| 97 const SkPM4f src[], int count, const SkAlpha aa[ ]) { | 150 const SkPM4f src[], int count, const SkAlpha aa[ ]) { |
| 98 if (aa) { | 151 if (aa) { |
| 99 for (int i = 0; i < count; ++i) { | 152 for (int i = 0; i < count; ++i) { |
| 100 const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src[i].fVec)); | 153 const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src[i].fVec)); |
| 101 const Sk4f d4 = load_from_dst<D>(dst[i]); | 154 const Sk4f d4 = load_from_dst<D>(dst[i]); |
| 102 dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); | 155 dst[i] = store_to_dst<D>(lerp_by_coverage(s4, d4, aa[i])); |
| 103 } | 156 } |
| 104 } else { | 157 } else { |
| 105 for (int i = 0; i < count; ++i) { | 158 for (int i = 0; i < count; ++i) { |
| 106 const Sk4f s4 = unit_to_dst_bias<D>(Sk4f::Load(src[i].fVec)); | 159 const Sk4f s4 = unit_to_bias<D>(Sk4f::Load(src[i].fVec)); |
| 107 dst[i] = store_to_dst<D>(s4); | 160 dst[i] = store_to_dst<D>(s4); |
| 108 } | 161 } |
| 109 } | 162 } |
| 110 } | 163 } |
| 111 | 164 |
| 112 const U64ProcPair gU64Procs_Src[] = { | 165 const U64ProcPair gU64Procs_Src[] = { |
| 113 { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 alpha | 166 { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 alpha |
| 114 { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 opaque | 167 { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 opaque |
| 115 { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 alpha | 168 { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 alpha |
| 116 { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 opaque | 169 { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 opaque |
| 117 }; | 170 }; |
| 118 | 171 |
| 119 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 172 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 120 | 173 |
| 121 template <DstType D> void srcover_1(const SkXfermode::U64State& state, uint64_t dst[], | 174 template <DstType D> void srcover_1(const SkXfermode::U64State& state, uint64_t dst[], |
| 122 const SkPM4f& src, int count, const SkAlpha aa[]) { | 175 const SkPM4f& src, int count, const SkAlpha aa[]) { |
| 123 const Sk4f s4 = Sk4f::Load(src.fVec); | 176 const Sk4f s4 = Sk4f::Load(src.fVec); |
| 124 const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); | 177 const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); |
| 125 const Sk4f s4bias = unit_to_dst_bias<D>(s4); | 178 const Sk4f s4bias = unit_to_bias<D>(s4); |
| 126 for (int i = 0; i < count; ++i) { | 179 for (int i = 0; i < count; ++i) { |
| 127 const Sk4f d4bias = load_from_dst<D>(dst[i]); | 180 const Sk4f d4bias = load_from_dst<D>(dst[i]); |
| 128 const Sk4f r4bias = s4bias + d4bias * dst_scale; | 181 const Sk4f r4bias = s4bias + d4bias * dst_scale; |
| 129 if (aa) { | 182 if (aa) { |
| 130 dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); | 183 dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); |
| 131 } else { | 184 } else { |
| 132 dst[i] = store_to_dst<D>(r4bias); | 185 dst[i] = store_to_dst<D>(r4bias); |
| 133 } | 186 } |
| 134 } | 187 } |
| 135 } | 188 } |
| 136 | 189 |
| 137 template <DstType D> void srcover_n(const SkXfermode::U64State& state, uint64_t dst[], | 190 template <DstType D> void srcover_n(const SkXfermode::U64State& state, uint64_t dst[], |
| 138 const SkPM4f src[], int count, const SkAlpha aa[]) { | 191 const SkPM4f src[], int count, const SkAlpha aa[]) { |
| 139 for (int i = 0; i < count; ++i) { | 192 for (int i = 0; i < count; ++i) { |
| 140 const Sk4f s4 = Sk4f::Load(src[i].fVec); | 193 const Sk4f s4 = Sk4f::Load(src[i].fVec); |
| 141 const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); | 194 const Sk4f dst_scale = Sk4f(1 - get_alpha(s4)); |
| 142 const Sk4f s4bias = unit_to_dst_bias<D>(s4); | 195 const Sk4f s4bias = unit_to_bias<D>(s4); |
| 143 const Sk4f d4bias = load_from_dst<D>(dst[i]); | 196 const Sk4f d4bias = load_from_dst<D>(dst[i]); |
| 144 const Sk4f r4bias = s4bias + d4bias * dst_scale; | 197 const Sk4f r4bias = s4bias + d4bias * dst_scale; |
| 145 if (aa) { | 198 if (aa) { |
| 146 dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); | 199 dst[i] = store_to_dst<D>(lerp_by_coverage(r4bias, d4bias, aa[i])); |
| 147 } else { | 200 } else { |
| 148 dst[i] = store_to_dst<D>(r4bias); | 201 dst[i] = store_to_dst<D>(r4bias); |
| 149 } | 202 } |
| 150 } | 203 } |
| 151 } | 204 } |
| 152 | 205 |
| 153 const U64ProcPair gU64Procs_SrcOver[] = { | 206 const U64ProcPair gU64Procs_SrcOver[] = { |
| 154 { srcover_1<kU16_Dst>, srcover_n<kU16_Dst> }, // U16 alpha | 207 { srcover_1<kU16_Dst>, srcover_n<kU16_Dst> }, // U16 alpha |
| 155 { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 opaque | 208 { src_1<kU16_Dst>, src_n<kU16_Dst> }, // U16 opaque |
| 156 { srcover_1<kF16_Dst>, srcover_n<kF16_Dst> }, // F16 alpha | 209 { srcover_1<kF16_Dst>, srcover_n<kF16_Dst> }, // F16 alpha |
| 157 { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 opaque | 210 { src_1<kF16_Dst>, src_n<kF16_Dst> }, // F16 opaque |
| 158 }; | 211 }; |
| 159 | 212 |
| 160 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 213 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| 161 | 214 |
| 162 static U64ProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) { | 215 static U64ProcPair find_procs(SkXfermode::Mode mode, uint32_t flags) { |
| 163 SkASSERT(0 == (flags & ~3)); | 216 SkASSERT(0 == (flags & ~3)); |
| 164 flags &= 3; | 217 flags &= 3; |
| 165 | 218 |
| 166 switch (mode) { | 219 switch (mode) { |
| 167 case SkXfermode::kSrc_Mode: return gU64Procs_Src[flags]; | 220 case SkXfermode::kSrc_Mode: return gU64Procs_Src[flags]; |
| 168 case SkXfermode::kSrcOver_Mode: return gU64Procs_SrcOver[flags]; | 221 case SkXfermode::kSrcOver_Mode: return gU64Procs_SrcOver[flags]; |
| 169 default: | 222 default: |
| 170 break; | 223 break; |
| 171 } | 224 } |
| 172 return { nullptr, nullptr }; | 225 return gU64Procs_General[flags]; |
| 173 } | 226 } |
| 174 | 227 |
| 175 SkXfermode::U64Proc1 SkXfermode::GetU64Proc1(Mode mode, uint32_t flags) { | 228 SkXfermode::U64Proc1 SkXfermode::GetU64Proc1(Mode mode, uint32_t flags) { |
| 176 return find_procs(mode, flags).fP1; | 229 return find_procs(mode, flags).fP1; |
| 177 } | 230 } |
| 178 | 231 |
| 179 SkXfermode::U64ProcN SkXfermode::GetU64ProcN(Mode mode, uint32_t flags) { | 232 SkXfermode::U64ProcN SkXfermode::GetU64ProcN(Mode mode, uint32_t flags) { |
| 180 return find_procs(mode, flags).fPN; | 233 return find_procs(mode, flags).fPN; |
| 181 } | 234 } |
| OLD | NEW |