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 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { | 1326 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
1327 return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + | 1327 return Sk4px::Wide(src.mulWiden(dst.alphas().inv()) + |
1328 dst.mulWiden(src.alphas().inv()) + | 1328 dst.mulWiden(src.alphas().inv()) + |
1329 src.mulWiden(dst)) | 1329 src.mulWiden(dst)) |
1330 .div255RoundNarrow(); | 1330 .div255RoundNarrow(); |
1331 } | 1331 } |
1332 static const bool kFoldCoverageIntoSrcAlpha = false; | 1332 static const bool kFoldCoverageIntoSrcAlpha = false; |
1333 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; | 1333 static const SkXfermode::Mode kMode = SkXfermode::kMultiply_Mode; |
1334 }; | 1334 }; |
1335 | 1335 |
| 1336 // [ sa + da - sa*da, sc + dc - 2*min(sc*da, dc*sa) ] (And notice sa*da == min(
sa*da, da*sa).) |
1336 struct Difference4f { | 1337 struct Difference4f { |
1337 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1338 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1338 const Sk4f inv255(gInv255); | 1339 const Sk4f inv255(gInv255); |
1339 Sk4f sa = Sk4f(src.a()); | 1340 Sk4f sa = Sk4f(src.a()); |
1340 Sk4f da = Sk4f(dst.a()); | 1341 Sk4f da = Sk4f(dst.a()); |
1341 Sk4f sc = src; | 1342 Sk4f sc = src; |
1342 Sk4f dc = dst; | 1343 Sk4f dc = dst; |
1343 Sk4f min = Sk4f::Min(sc * da, dc * sa) * inv255; | 1344 Sk4f min = Sk4f::Min(sc * da, dc * sa) * inv255; |
1344 Sk4f ra = sc + dc - min; | 1345 Sk4f ra = sc + dc - min; |
1345 return check_as_pmfloat(ra - min * SkPMFloat(0, 1, 1, 1)); | 1346 return check_as_pmfloat(ra - min * SkPMFloat(0, 1, 1, 1)); |
1346 } | 1347 } |
| 1348 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1349 auto m = Sk4px::Wide(Sk16h::Min(src.mulWiden(dst.alphas()), dst.mulWiden
(src.alphas()))) |
| 1350 .div255RoundNarrow(); |
| 1351 // There's no chance of underflow, and if we subtract m before adding sr
c+dst, no overflow. |
| 1352 return (src - m) + (dst - m.zeroAlphas()); |
| 1353 } |
1347 static const bool kFoldCoverageIntoSrcAlpha = false; | 1354 static const bool kFoldCoverageIntoSrcAlpha = false; |
1348 static const SkXfermode::Mode kMode = SkXfermode::kDifference_Mode; | 1355 static const SkXfermode::Mode kMode = SkXfermode::kDifference_Mode; |
1349 }; | 1356 }; |
1350 | 1357 |
| 1358 // [ sa + da - sa*da, sc + dc - 2*sc*dc ] |
1351 struct Exclusion4f { | 1359 struct Exclusion4f { |
1352 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1360 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
1353 const Sk4f inv255(gInv255); | 1361 const Sk4f inv255(gInv255); |
1354 Sk4f sc = src; | 1362 Sk4f sc = src; |
1355 Sk4f dc = dst; | 1363 Sk4f dc = dst; |
1356 Sk4f prod = sc * dc * inv255; | 1364 Sk4f prod = sc * dc * inv255; |
1357 Sk4f ra = sc + dc - prod; | 1365 Sk4f ra = sc + dc - prod; |
1358 return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1)); | 1366 return check_as_pmfloat(ra - prod * SkPMFloat(0, 1, 1, 1)); |
1359 } | 1367 } |
| 1368 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1369 auto p = src.mulWiden(dst).div255RoundNarrow(); |
| 1370 // There's no chance of underflow, and if we subtract p before adding sr
c+dst, no overflow. |
| 1371 return (src - p) + (dst - p.zeroAlphas()); |
| 1372 } |
1360 static const bool kFoldCoverageIntoSrcAlpha = false; | 1373 static const bool kFoldCoverageIntoSrcAlpha = false; |
1361 static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; | 1374 static const SkXfermode::Mode kMode = SkXfermode::kExclusion_Mode; |
1362 }; | 1375 }; |
1363 | 1376 |
1364 template <typename ProcType> | 1377 template <typename ProcType> |
1365 class SkT4fXfermode : public SkProcCoeffXfermode { | 1378 class SkT4fXfermode : public SkProcCoeffXfermode { |
1366 public: | 1379 public: |
1367 static SkXfermode* Create(const ProcCoeff& rec) { | 1380 static SkXfermode* Create(const ProcCoeff& rec) { |
1368 return SkNEW_ARGS(SkT4fXfermode, (rec)); | 1381 return SkNEW_ARGS(SkT4fXfermode, (rec)); |
1369 } | 1382 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1406 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { | 1419 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { |
1407 if (NULL == aa) { | 1420 if (NULL == aa) { |
1408 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr
c4) { | 1421 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr
c4) { |
1409 return ProcType::Xfer(src4, dst4); | 1422 return ProcType::Xfer(src4, dst4); |
1410 }); | 1423 }); |
1411 } else { | 1424 } else { |
1412 Sk4px::MapDstSrcAlpha(n, dst, src, aa, | 1425 Sk4px::MapDstSrcAlpha(n, dst, src, aa, |
1413 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha
) { | 1426 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha
) { |
1414 // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=2
4-bit intermediates. | 1427 // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=2
4-bit intermediates. |
1415 Sk4px res4 = ProcType::Xfer(src4, dst4); | 1428 Sk4px res4 = ProcType::Xfer(src4, dst4); |
1416 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk16b(25
5)-alpha)) | 1429 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk4px(al
pha).inv())) |
1417 .div255RoundNarrow(); | 1430 .div255RoundNarrow(); |
1418 }); | 1431 }); |
1419 } | 1432 } |
1420 } | 1433 } |
1421 | 1434 |
1422 private: | 1435 private: |
1423 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} | 1436 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} |
1424 | 1437 |
1425 typedef SkProcCoeffXfermode INHERITED; | 1438 typedef SkProcCoeffXfermode INHERITED; |
1426 }; | 1439 }; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1480 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; | 1493 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; |
1481 | 1494 |
1482 ProcCoeff rec = gProcCoeffs[mode]; | 1495 ProcCoeff rec = gProcCoeffs[mode]; |
1483 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | 1496 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); |
1484 if (pp != NULL) { | 1497 if (pp != NULL) { |
1485 rec.fProc = pp; | 1498 rec.fProc = pp; |
1486 } | 1499 } |
1487 | 1500 |
1488 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) | 1501 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) |
1489 switch (mode) { | 1502 switch (mode) { |
1490 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Creat
e(rec); | 1503 case SkXfermode::kSrcATop_Mode: return SkT4pxXfermode<SrcATop4f>::Cre
ate(rec); |
1491 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Creat
e(rec); | 1504 case SkXfermode::kDstATop_Mode: return SkT4pxXfermode<DstATop4f>::Cre
ate(rec); |
1492 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(re
c); | 1505 case SkXfermode::kXor_Mode: return SkT4pxXfermode<Xor4f>::Create(
rec); |
1493 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create(r
ec); | 1506 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create
(rec); |
1494 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Crea
te(rec); | 1507 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Cr
eate(rec); |
1495 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Create
(rec); | 1508 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Crea
te(rec); |
1496 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Crea
te(rec); | 1509 case SkXfermode::kMultiply_Mode: return SkT4pxXfermode<Multiply4f>::Cr
eate(rec); |
| 1510 case SkXfermode::kDifference_Mode: return SkT4pxXfermode<Difference4f>::
Create(rec); |
| 1511 case SkXfermode::kExclusion_Mode: return SkT4pxXfermode<Exclusion4f>::C
reate(rec); |
1497 default: break; | 1512 default: break; |
1498 } | 1513 } |
1499 #endif | 1514 #endif |
1500 | 1515 |
1501 #if defined(SK_4F_XFERMODES_ARE_FAST) | 1516 #if defined(SK_4F_XFERMODES_ARE_FAST) |
1502 switch (mode) { | 1517 switch (mode) { |
1503 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea
te(rec); | 1518 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea
te(rec); |
1504 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea
te(rec); | 1519 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea
te(rec); |
1505 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r
ec); | 1520 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r
ec); |
1506 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create(
rec); | 1521 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create(
rec); |
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1806 } else { | 1821 } else { |
1807 proc16 = rec.fProc16_General; | 1822 proc16 = rec.fProc16_General; |
1808 } | 1823 } |
1809 } | 1824 } |
1810 return proc16; | 1825 return proc16; |
1811 } | 1826 } |
1812 | 1827 |
1813 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1828 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1814 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1829 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1815 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1830 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |