OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 #ifndef Sk4pxXfermode_DEFINED | 8 #ifndef Sk4pxXfermode_DEFINED |
9 #define Sk4pxXfermode_DEFINED | 9 #define Sk4pxXfermode_DEFINED |
10 | 10 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 return ProcType::Xfer(src4, dst4); | 215 return ProcType::Xfer(src4, dst4); |
216 }); | 216 }); |
217 } else { | 217 } else { |
218 Sk4px::MapDstSrcAlpha(n, dst, src, aa, | 218 Sk4px::MapDstSrcAlpha(n, dst, src, aa, |
219 [&](const Sk4px& dst4, const Sk4px& src4, const Sk4px& alpha
) { | 219 [&](const Sk4px& dst4, const Sk4px& src4, const Sk4px& alpha
) { |
220 return xfer_aa<ProcType>(src4, dst4, alpha); | 220 return xfer_aa<ProcType>(src4, dst4, alpha); |
221 }); | 221 }); |
222 } | 222 } |
223 } | 223 } |
224 | 224 |
225 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[]
) const override { | |
226 if (NULL == aa) { | |
227 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr
c4) { | |
228 return ProcType::Xfer(src4, dst4); | |
229 }); | |
230 } else { | |
231 Sk4px::MapDstSrcAlpha(n, dst, src, aa, | |
232 [&](const Sk4px& dst4, const Sk4px& src4, const Sk4px& alpha
) { | |
233 return xfer_aa<ProcType>(src4, dst4, alpha); | |
234 }); | |
235 } | |
236 } | |
237 | |
238 private: | 225 private: |
239 SkT4pxXfermode(const ProcCoeff& rec) : INHERITED(rec, ProcType::kMode) {} | 226 SkT4pxXfermode(const ProcCoeff& rec) : INHERITED(rec, ProcType::kMode) {} |
240 | 227 |
241 typedef SkProcCoeffXfermode INHERITED; | 228 typedef SkProcCoeffXfermode INHERITED; |
242 }; | 229 }; |
243 | 230 |
244 template <typename ProcType> | 231 template <typename ProcType> |
245 class SkTPMFloatXfermode : public SkProcCoeffXfermode { | 232 class SkTPMFloatXfermode : public SkProcCoeffXfermode { |
246 public: | 233 public: |
247 static SkProcCoeffXfermode* Create(const ProcCoeff& rec) { | 234 static SkProcCoeffXfermode* Create(const ProcCoeff& rec) { |
248 return SkNEW_ARGS(SkTPMFloatXfermode, (rec)); | 235 return SkNEW_ARGS(SkTPMFloatXfermode, (rec)); |
249 } | 236 } |
250 | 237 |
251 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { | 238 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { |
252 for (int i = 0; i < n; i++) { | 239 for (int i = 0; i < n; i++) { |
253 dst[i] = aa ? this->xfer32(dst[i], src[i], aa[i]) | 240 SkPMFloat s(src[i]), |
254 : this->xfer32(dst[i], src[i]); | 241 d(dst[i]), |
255 } | 242 b(ProcType::Xfer(s,d)); |
256 } | 243 if (aa) { |
257 | 244 // We do aa in full float precision before going back down to by
tes, because we can! |
258 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[]
) const override { | 245 SkPMFloat a = Sk4f(aa[i]) * Sk4f(1.0f/255); |
259 for (int i = 0; i < n; i++) { | 246 b = b*a + d*(Sk4f(1)-a); |
260 SkPMColor dst32 = SkPixel16ToPixel32(dst[i]); | 247 } |
261 dst32 = aa ? this->xfer32(dst32, src[i], aa[i]) | 248 dst[i] = b.round(); |
262 : this->xfer32(dst32, src[i]); | |
263 dst[i] = SkPixel32ToPixel16(dst32); | |
264 } | 249 } |
265 } | 250 } |
266 | 251 |
267 private: | 252 private: |
268 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src) const { | |
269 return ProcType::Xfer(SkPMFloat(src), SkPMFloat(dst)).round(); | |
270 } | |
271 | |
272 inline SkPMColor xfer32(SkPMColor dst, SkPMColor src, SkAlpha aa) const { | |
273 SkPMFloat s(src), | |
274 d(dst), | |
275 b(ProcType::Xfer(s,d)); | |
276 // We do aa in full float precision before going back down to bytes, bec
ause we can! | |
277 SkPMFloat a = Sk4f(aa) * Sk4f(1.0f/255); | |
278 b = b*a + d*(Sk4f(1)-a); | |
279 return b.round(); | |
280 } | |
281 | |
282 SkTPMFloatXfermode(const ProcCoeff& rec) : INHERITED(rec, ProcType::kMode) {
} | 253 SkTPMFloatXfermode(const ProcCoeff& rec) : INHERITED(rec, ProcType::kMode) {
} |
283 | 254 |
284 typedef SkProcCoeffXfermode INHERITED; | 255 typedef SkProcCoeffXfermode INHERITED; |
285 }; | 256 }; |
286 | 257 |
287 static SkProcCoeffXfermode* SkCreate4pxXfermode(const ProcCoeff& rec, SkXfermode
::Mode mode) { | 258 static SkProcCoeffXfermode* SkCreate4pxXfermode(const ProcCoeff& rec, SkXfermode
::Mode mode) { |
288 #if !defined(SK_CPU_ARM32) || defined(SK_ARM_HAS_NEON) | 259 #if !defined(SK_CPU_ARM32) || defined(SK_ARM_HAS_NEON) |
289 switch (mode) { | 260 switch (mode) { |
290 case SkXfermode::kClear_Mode: return SkT4pxXfermode<Clear>::Create(
rec); | 261 case SkXfermode::kClear_Mode: return SkT4pxXfermode<Clear>::Create(
rec); |
291 case SkXfermode::kSrc_Mode: return SkT4pxXfermode<Src>::Create(re
c); | 262 case SkXfermode::kSrc_Mode: return SkT4pxXfermode<Src>::Create(re
c); |
(...skipping 23 matching lines...) Expand all Loading... |
315 case SkXfermode::kSoftLight_Mode: return SkTPMFloatXfermode<SoftLight>:
:Create(rec); | 286 case SkXfermode::kSoftLight_Mode: return SkTPMFloatXfermode<SoftLight>:
:Create(rec); |
316 default: break; | 287 default: break; |
317 } | 288 } |
318 #endif | 289 #endif |
319 return nullptr; | 290 return nullptr; |
320 } | 291 } |
321 | 292 |
322 } // namespace | 293 } // namespace |
323 | 294 |
324 #endif//Sk4pxXfermode_DEFINED | 295 #endif//Sk4pxXfermode_DEFINED |
OLD | NEW |