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 |