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 |