OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "SkXfermode.h" | 9 #include "SkXfermode.h" |
10 #include "SkXfermode_opts_SSE2.h" | 10 #include "SkXfermode_opts_SSE2.h" |
(...skipping 1223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1234 } | 1234 } |
1235 // [ Sa + Da - Sa*Da, Sc + Dc - 2*Sc*Dc ] | 1235 // [ Sa + Da - Sa*Da, Sc + Dc - 2*Sc*Dc ] |
1236 XFERMODE(Exclusion) { | 1236 XFERMODE(Exclusion) { |
1237 auto p = s.fastMulDiv255Round(d); | 1237 auto p = s.fastMulDiv255Round(d); |
1238 // There's no chance of underflow, and if we subtract p before adding src+ds
t, no overflow. | 1238 // There's no chance of underflow, and if we subtract p before adding src+ds
t, no overflow. |
1239 return (s - p) + (d - p.zeroAlphas()); | 1239 return (s - p) + (d - p.zeroAlphas()); |
1240 } | 1240 } |
1241 | 1241 |
1242 #undef XFERMODE | 1242 #undef XFERMODE |
1243 | 1243 |
| 1244 // A reasonable fallback mode for doing AA is to simply apply the transfermode f
irst, |
| 1245 // then linearly interpolate the AA. |
| 1246 template <typename Mode> |
| 1247 static Sk4px xfer_aa(const Sk4px& s, const Sk4px& d, const Sk16b& aa) { |
| 1248 Sk4px noAA = Mode::Xfer(s, d); |
| 1249 return Sk4px::Wide(noAA.mulWiden(aa) + d.mulWiden(Sk4px(aa).inv())) |
| 1250 .div255RoundNarrow(); |
| 1251 } |
| 1252 |
| 1253 // For some transfermodes we specialize AA, either for correctness or performanc
e. |
| 1254 #ifndef SK_NO_SPECIALIZED_AA_XFERMODES |
| 1255 #define XFERMODE_AA(Name) \ |
| 1256 template <> Sk4px xfer_aa<Name>(const Sk4px& s, const Sk4px& d, const Sk
16b& aa) |
| 1257 |
| 1258 // Plus' clamp needs to happen after AA. skia:3852 |
| 1259 XFERMODE_AA(Plus) { // [ clamp(D + AA*S) ] |
| 1260 // We implement this as D + Min(S*AA, (1-D)) to fit the arguments to Min
in 16 bits. |
| 1261 return d + |
| 1262 Sk4px::Wide(Sk16h::Min(s.mulWiden(aa), d.inv().mul255Widen())).div25
5RoundNarrow(); |
| 1263 } |
| 1264 |
| 1265 #undef XFERMODE_AA |
| 1266 #endif |
| 1267 |
1244 template <typename ProcType> | 1268 template <typename ProcType> |
1245 class SkT4pxXfermode : public SkProcCoeffXfermode { | 1269 class SkT4pxXfermode : public SkProcCoeffXfermode { |
1246 public: | 1270 public: |
1247 static SkXfermode* Create(const ProcCoeff& rec) { | 1271 static SkXfermode* Create(const ProcCoeff& rec) { |
1248 return SkNEW_ARGS(SkT4pxXfermode, (rec)); | 1272 return SkNEW_ARGS(SkT4pxXfermode, (rec)); |
1249 } | 1273 } |
1250 | 1274 |
1251 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { | 1275 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { |
1252 if (NULL == aa) { | 1276 if (NULL == aa) { |
1253 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr
c4) { | 1277 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr
c4) { |
1254 return ProcType::Xfer(src4, dst4); | 1278 return ProcType::Xfer(src4, dst4); |
1255 }); | 1279 }); |
1256 } else { | 1280 } else { |
1257 Sk4px::MapDstSrcAlpha(n, dst, src, aa, | 1281 Sk4px::MapDstSrcAlpha(n, dst, src, aa, |
1258 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha
) { | 1282 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha
) { |
1259 Sk4px res4 = ProcType::Xfer(src4, dst4); | 1283 return xfer_aa<ProcType>(src4, dst4, alpha); |
1260 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk4px(al
pha).inv())) | |
1261 .div255RoundNarrow(); | |
1262 }); | 1284 }); |
1263 } | 1285 } |
1264 } | 1286 } |
1265 | 1287 |
1266 private: | 1288 private: |
1267 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} | 1289 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} |
1268 | 1290 |
1269 typedef SkProcCoeffXfermode INHERITED; | 1291 typedef SkProcCoeffXfermode INHERITED; |
1270 }; | 1292 }; |
1271 | 1293 |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 } else { | 1668 } else { |
1647 proc16 = rec.fProc16_General; | 1669 proc16 = rec.fProc16_General; |
1648 } | 1670 } |
1649 } | 1671 } |
1650 return proc16; | 1672 return proc16; |
1651 } | 1673 } |
1652 | 1674 |
1653 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1675 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1654 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1676 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1655 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1677 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |