| 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 |
| 11 #include "Sk4px.h" | 11 #include "Sk4px.h" |
| 12 #include "SkMSAN.h" |
| 12 #include "SkNx.h" | 13 #include "SkNx.h" |
| 13 #include "SkXfermode_proccoeff.h" | 14 #include "SkXfermode_proccoeff.h" |
| 14 | 15 |
| 15 namespace { | 16 namespace { |
| 16 | 17 |
| 17 // Most xfermodes can be done most efficiently 4 pixels at a time in 8 or 16-bit
fixed point. | 18 // Most xfermodes can be done most efficiently 4 pixels at a time in 8 or 16-bit
fixed point. |
| 18 #define XFERMODE(Xfermode) \ | 19 #define XFERMODE(Xfermode) \ |
| 19 struct Xfermode { Sk4px operator()(const Sk4px&, const Sk4px&) const; }; \ | 20 struct Xfermode { Sk4px operator()(const Sk4px&, const Sk4px&) const; }; \ |
| 20 inline Sk4px Xfermode::operator()(const Sk4px& d, const Sk4px& s) const | 21 inline Sk4px Xfermode::operator()(const Sk4px& d, const Sk4px& s) const |
| 21 | 22 |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 #define XFERMODE_AA(Xfermode) \ | 196 #define XFERMODE_AA(Xfermode) \ |
| 196 template <> Sk4px xfer_aa<Xfermode>(const Sk4px& d, const Sk4px& s, const Sk
4px& aa) | 197 template <> Sk4px xfer_aa<Xfermode>(const Sk4px& d, const Sk4px& s, const Sk
4px& aa) |
| 197 | 198 |
| 198 // Plus' clamp needs to happen after AA. skia:3852 | 199 // Plus' clamp needs to happen after AA. skia:3852 |
| 199 XFERMODE_AA(Plus) { // [ clamp( (1-AA)D + (AA)(S+D) ) == clamp(D + AA*S) ] | 200 XFERMODE_AA(Plus) { // [ clamp( (1-AA)D + (AA)(S+D) ) == clamp(D + AA*S) ] |
| 200 return d.saturatedAdd(s.approxMulDiv255(aa)); | 201 return d.saturatedAdd(s.approxMulDiv255(aa)); |
| 201 } | 202 } |
| 202 | 203 |
| 203 #undef XFERMODE_AA | 204 #undef XFERMODE_AA |
| 204 | 205 |
| 206 // Src and Clear modes are safe to use with unitialized dst buffers, |
| 207 // even if the implementation branches based on bytes from dst (e.g. asserts in
Debug mode). |
| 208 // For those modes, just lie to MSAN that dst is always intialized. |
| 209 template <typename Xfermode> static void mark_dst_initialized_if_safe(void*, voi
d*) {} |
| 210 template <> void mark_dst_initialized_if_safe<Src>(void* dst, void* end) { |
| 211 sk_msan_mark_initialized(dst, end, "Src doesn't read dst."); |
| 212 } |
| 213 template <> void mark_dst_initialized_if_safe<Clear>(void* dst, void* end) { |
| 214 sk_msan_mark_initialized(dst, end, "Clear doesn't read dst."); |
| 215 } |
| 216 |
| 205 template <typename Xfermode> | 217 template <typename Xfermode> |
| 206 class Sk4pxXfermode : public SkProcCoeffXfermode { | 218 class Sk4pxXfermode : public SkProcCoeffXfermode { |
| 207 public: | 219 public: |
| 208 Sk4pxXfermode(const ProcCoeff& rec, SkXfermode::Mode mode) | 220 Sk4pxXfermode(const ProcCoeff& rec, SkXfermode::Mode mode) |
| 209 : INHERITED(rec, mode) {} | 221 : INHERITED(rec, mode) {} |
| 210 | 222 |
| 211 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { | 223 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { |
| 224 mark_dst_initialized_if_safe<Xfermode>(dst, dst+n); |
| 212 if (nullptr == aa) { | 225 if (nullptr == aa) { |
| 213 Sk4px::MapDstSrc(n, dst, src, Xfermode()); | 226 Sk4px::MapDstSrc(n, dst, src, Xfermode()); |
| 214 } else { | 227 } else { |
| 215 Sk4px::MapDstSrcAlpha(n, dst, src, aa, xfer_aa<Xfermode>); | 228 Sk4px::MapDstSrcAlpha(n, dst, src, aa, xfer_aa<Xfermode>); |
| 216 } | 229 } |
| 217 } | 230 } |
| 218 | 231 |
| 219 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[]
) const override { | 232 void xfer16(uint16_t dst[], const SkPMColor src[], int n, const SkAlpha aa[]
) const override { |
| 233 mark_dst_initialized_if_safe<Xfermode>(dst, dst+n); |
| 220 SkPMColor dst32[4]; | 234 SkPMColor dst32[4]; |
| 221 while (n >= 4) { | 235 while (n >= 4) { |
| 222 dst32[0] = SkPixel16ToPixel32(dst[0]); | 236 dst32[0] = SkPixel16ToPixel32(dst[0]); |
| 223 dst32[1] = SkPixel16ToPixel32(dst[1]); | 237 dst32[1] = SkPixel16ToPixel32(dst[1]); |
| 224 dst32[2] = SkPixel16ToPixel32(dst[2]); | 238 dst32[2] = SkPixel16ToPixel32(dst[2]); |
| 225 dst32[3] = SkPixel16ToPixel32(dst[3]); | 239 dst32[3] = SkPixel16ToPixel32(dst[3]); |
| 226 | 240 |
| 227 this->xfer32(dst32, src, 4, aa); | 241 this->xfer32(dst32, src, 4, aa); |
| 228 | 242 |
| 229 dst[0] = SkPixel32ToPixel16(dst32[0]); | 243 dst[0] = SkPixel32ToPixel16(dst32[0]); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 #undef CASE | 351 #undef CASE |
| 338 | 352 |
| 339 default: break; | 353 default: break; |
| 340 } | 354 } |
| 341 return nullptr; | 355 return nullptr; |
| 342 } | 356 } |
| 343 | 357 |
| 344 } // namespace SK_OPTS_NS | 358 } // namespace SK_OPTS_NS |
| 345 | 359 |
| 346 #endif//Sk4pxXfermode_DEFINED | 360 #endif//Sk4pxXfermode_DEFINED |
| OLD | NEW |