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 "SkPM4fPriv.h" | 8 #include "SkPM4fPriv.h" |
9 #include "SkUtils.h" | 9 #include "SkUtils.h" |
10 #include "SkXfermode.h" | 10 #include "SkXfermode.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 } | 182 } |
183 Sk4f r4 = Sk4f::Load(src[i].fVec); // src always overrides dst | 183 Sk4f r4 = Sk4f::Load(src[i].fVec); // src always overrides dst |
184 if (a != 0xFF) { | 184 if (a != 0xFF) { |
185 Sk4f d4 = load_dst<D>(dst[i]); | 185 Sk4f d4 = load_dst<D>(dst[i]); |
186 r4 = lerp(r4, d4, a); | 186 r4 = lerp(r4, d4, a); |
187 } | 187 } |
188 dst[i] = store_dst<D>(r4); | 188 dst[i] = store_dst<D>(r4); |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
| 192 static Sk4f lerp(const Sk4f& src, const Sk4f& dst, const Sk4f& src_scale) { |
| 193 return dst + (src - dst) * src_scale; |
| 194 } |
| 195 |
192 template <DstType D> void src_1(const SkXfermode::PM4fState& state, uint32_t dst
[], | 196 template <DstType D> void src_1(const SkXfermode::PM4fState& state, uint32_t dst
[], |
193 const SkPM4f& src, int count, const SkAlpha aa[]
) { | 197 const SkPM4f& src, int count, const SkAlpha aa[]
) { |
194 const Sk4f r4 = Sk4f::Load(src.fVec); // src always overrides dst | 198 const Sk4f s4 = Sk4f::Load(src.fVec); |
195 const uint32_t r32 = store_dst<D>(r4); | |
196 | 199 |
197 if (aa) { | 200 if (aa) { |
| 201 if (D == kLinear_Dst) { |
| 202 // operate in bias-255 space for src and dst |
| 203 const Sk4f& s4_255 = s4 * Sk4f(255); |
| 204 while (count >= 4) { |
| 205 Sk4f aa4 = SkNx_cast<float>(Sk4b::Load(aa)) * Sk4f(1/255.f); |
| 206 Sk4f r0 = lerp(s4_255, to_4f(dst[0]), Sk4f(aa4.kth<0>())) + Sk4f
(0.5f); |
| 207 Sk4f r1 = lerp(s4_255, to_4f(dst[1]), Sk4f(aa4.kth<1>())) + Sk4f
(0.5f); |
| 208 Sk4f r2 = lerp(s4_255, to_4f(dst[2]), Sk4f(aa4.kth<2>())) + Sk4f
(0.5f); |
| 209 Sk4f r3 = lerp(s4_255, to_4f(dst[3]), Sk4f(aa4.kth<3>())) + Sk4f
(0.5f); |
| 210 Sk4f_ToBytes((uint8_t*)dst, r0, r1, r2, r3); |
| 211 |
| 212 dst += 4; |
| 213 aa += 4; |
| 214 count -= 4; |
| 215 } |
| 216 } else { // kSRGB |
| 217 while (count >= 4) { |
| 218 Sk4f aa4 = SkNx_cast<float>(Sk4b::Load(aa)) * Sk4f(1/255.0f); |
| 219 |
| 220 /* If we ever natively support convert 255_linear -> 255_srgb,
then perhaps |
| 221 * it would be faster (and possibly allow more code sharing wit
h kLinear) to |
| 222 * stay in that space. |
| 223 */ |
| 224 Sk4f r0 = lerp(s4, load_dst<D>(dst[0]), Sk4f(aa4.kth<0>())); |
| 225 Sk4f r1 = lerp(s4, load_dst<D>(dst[1]), Sk4f(aa4.kth<1>())); |
| 226 Sk4f r2 = lerp(s4, load_dst<D>(dst[2]), Sk4f(aa4.kth<2>())); |
| 227 Sk4f r3 = lerp(s4, load_dst<D>(dst[3]), Sk4f(aa4.kth<3>())); |
| 228 Sk4f_ToBytes((uint8_t*)dst, |
| 229 linear_unit_to_srgb_255f(r0), |
| 230 linear_unit_to_srgb_255f(r1), |
| 231 linear_unit_to_srgb_255f(r2), |
| 232 linear_unit_to_srgb_255f(r3)); |
| 233 |
| 234 dst += 4; |
| 235 aa += 4; |
| 236 count -= 4; |
| 237 } |
| 238 } |
198 for (int i = 0; i < count; ++i) { | 239 for (int i = 0; i < count; ++i) { |
199 unsigned a = aa[i]; | 240 unsigned a = aa[i]; |
200 if (0 == a) { | 241 Sk4f d4 = load_dst<D>(dst[i]); |
201 continue; | 242 dst[i] = store_dst<D>(lerp(s4, d4, a)); |
202 } | |
203 if (a != 0xFF) { | |
204 Sk4f d4 = load_dst<D>(dst[i]); | |
205 dst[i] = store_dst<D>(lerp(r4, d4, a)); | |
206 } else { | |
207 dst[i] = r32; | |
208 } | |
209 } | 243 } |
210 } else { | 244 } else { |
211 sk_memset32(dst, r32, count); | 245 sk_memset32(dst, store_dst<D>(s4), count); |
212 } | 246 } |
213 } | 247 } |
214 | 248 |
215 const XferProcPair gProcs_Src[] = { | 249 const XferProcPair gProcs_Src[] = { |
216 { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear [alpha] | 250 { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear [alpha] |
217 { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear [opaque] | 251 { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear [opaque] |
218 { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb [alpha] | 252 { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb [alpha] |
219 { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb [opaque] | 253 { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb [opaque] |
220 }; | 254 }; |
221 | 255 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 | 415 |
382 SkXfermode::PM4fProc1 SkXfermode::getPM4fProc1(uint32_t flags) const { | 416 SkXfermode::PM4fProc1 SkXfermode::getPM4fProc1(uint32_t flags) const { |
383 Mode mode; | 417 Mode mode; |
384 return this->asMode(&mode) ? GetPM4fProc1(mode, flags) : xfer_pm4_proc_1; | 418 return this->asMode(&mode) ? GetPM4fProc1(mode, flags) : xfer_pm4_proc_1; |
385 } | 419 } |
386 | 420 |
387 SkXfermode::PM4fProcN SkXfermode::getPM4fProcN(uint32_t flags) const { | 421 SkXfermode::PM4fProcN SkXfermode::getPM4fProcN(uint32_t flags) const { |
388 Mode mode; | 422 Mode mode; |
389 return this->asMode(&mode) ? GetPM4fProcN(mode, flags) : xfer_pm4_proc_n; | 423 return this->asMode(&mode) ? GetPM4fProcN(mode, flags) : xfer_pm4_proc_n; |
390 } | 424 } |
OLD | NEW |