| 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" |
| 11 #include "SkXfermode_proccoeff.h" | 11 #include "SkXfermode_proccoeff.h" |
| 12 #include "Sk4px.h" |
| 12 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
| 13 #include "SkLazyPtr.h" | 14 #include "SkLazyPtr.h" |
| 14 #include "SkMathPriv.h" | 15 #include "SkMathPriv.h" |
| 15 #include "SkPMFloat.h" | 16 #include "SkPMFloat.h" |
| 16 #include "SkReadBuffer.h" | 17 #include "SkReadBuffer.h" |
| 17 #include "SkString.h" | 18 #include "SkString.h" |
| 18 #include "SkUtilsArm.h" | 19 #include "SkUtilsArm.h" |
| 19 #include "SkWriteBuffer.h" | 20 #include "SkWriteBuffer.h" |
| 20 | 21 |
| 21 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES | 22 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1262 } | 1263 } |
| 1263 static const bool kFoldCoverageIntoSrcAlpha = true; | 1264 static const bool kFoldCoverageIntoSrcAlpha = true; |
| 1264 static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode; | 1265 static const SkXfermode::Mode kMode = SkXfermode::kXor_Mode; |
| 1265 }; | 1266 }; |
| 1266 | 1267 |
| 1267 // kPlus_Mode [Sa + Da, Sc + Dc] | 1268 // kPlus_Mode [Sa + Da, Sc + Dc] |
| 1268 struct Plus4f { | 1269 struct Plus4f { |
| 1269 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1270 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| 1270 return check_as_pmfloat(clamp_255(src + dst)); | 1271 return check_as_pmfloat(clamp_255(src + dst)); |
| 1271 } | 1272 } |
| 1272 static const bool kFoldCoverageIntoSrcAlpha = true; | 1273 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1274 return src.saturatedAdd(dst); |
| 1275 } |
| 1276 static const bool kFoldCoverageIntoSrcAlpha = false; |
| 1273 static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode; | 1277 static const SkXfermode::Mode kMode = SkXfermode::kPlus_Mode; |
| 1274 }; | 1278 }; |
| 1275 | 1279 |
| 1276 // kModulate_Mode [Sa * Da, Sc * Dc] | 1280 // kModulate_Mode [Sa * Da, Sc * Dc] |
| 1277 struct Modulate4f { | 1281 struct Modulate4f { |
| 1278 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1282 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| 1279 const Sk4f inv255(gInv255); | 1283 const Sk4f inv255(gInv255); |
| 1280 return check_as_pmfloat(src * dst * inv255); | 1284 return check_as_pmfloat(src * dst * inv255); |
| 1281 } | 1285 } |
| 1286 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1287 return src.mulWiden(dst).div255RoundNarrow(); |
| 1288 } |
| 1282 static const bool kFoldCoverageIntoSrcAlpha = false; | 1289 static const bool kFoldCoverageIntoSrcAlpha = false; |
| 1283 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; | 1290 static const SkXfermode::Mode kMode = SkXfermode::kModulate_Mode; |
| 1284 }; | 1291 }; |
| 1285 | 1292 |
| 1286 // kScreen_Mode [S + D - S * D] | 1293 // kScreen_Mode [S + D - S * D] |
| 1287 struct Screen4f { | 1294 struct Screen4f { |
| 1288 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1295 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| 1289 const Sk4f inv255(gInv255); | 1296 const Sk4f inv255(gInv255); |
| 1290 return check_as_pmfloat(src + dst - src * dst * inv255); | 1297 return check_as_pmfloat(src + dst - src * dst * inv255); |
| 1291 } | 1298 } |
| 1299 static Sk4px Xfer(const Sk4px& src, const Sk4px& dst) { |
| 1300 // Doing the math as S + (1-S)*D or S + (D - S*D) means the add and subt
ract can be done |
| 1301 // in 8-bit space without overflow. S + (1-S)*D is a touch faster becau
se 255-x is an xor. |
| 1302 // TODO: do we need to explicitly implement / call Sk16b(255) ^ src ? |
| 1303 return src + Sk4px(Sk16b(255) - src).mulWiden(dst).div255RoundNarrow(); |
| 1304 } |
| 1292 static const bool kFoldCoverageIntoSrcAlpha = true; | 1305 static const bool kFoldCoverageIntoSrcAlpha = true; |
| 1293 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; | 1306 static const SkXfermode::Mode kMode = SkXfermode::kScreen_Mode; |
| 1294 }; | 1307 }; |
| 1295 | 1308 |
| 1296 struct Multiply4f { | 1309 struct Multiply4f { |
| 1297 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { | 1310 static SkPMFloat Xfer(const SkPMFloat& src, const SkPMFloat& dst) { |
| 1298 const Sk4f inv255(gInv255); | 1311 const Sk4f inv255(gInv255); |
| 1299 Sk4f sa = Sk4f(src.a()); | 1312 Sk4f sa = Sk4f(src.a()); |
| 1300 Sk4f da = Sk4f(dst.a()); | 1313 Sk4f da = Sk4f(dst.a()); |
| 1301 Sk4f sc = src; | 1314 Sk4f sc = src; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 dst[i] = SkPMFloat(res).round(); | 1376 dst[i] = SkPMFloat(res).round(); |
| 1364 } | 1377 } |
| 1365 } | 1378 } |
| 1366 } | 1379 } |
| 1367 | 1380 |
| 1368 private: | 1381 private: |
| 1369 SkT4fXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kMo
de) {} | 1382 SkT4fXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kMo
de) {} |
| 1370 | 1383 |
| 1371 typedef SkProcCoeffXfermode INHERITED; | 1384 typedef SkProcCoeffXfermode INHERITED; |
| 1372 }; | 1385 }; |
| 1386 |
| 1387 template <typename ProcType> |
| 1388 class SkT4pxXfermode : public SkProcCoeffXfermode { |
| 1389 public: |
| 1390 static SkXfermode* Create(const ProcCoeff& rec) { |
| 1391 return SkNEW_ARGS(SkT4pxXfermode, (rec)); |
| 1392 } |
| 1393 |
| 1394 void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[
]) const override { |
| 1395 if (NULL == aa) { |
| 1396 Sk4px::MapDstSrc(n, dst, src, [&](const Sk4px& dst4, const Sk4px& sr
c4) { |
| 1397 return ProcType::Xfer(src4, dst4); |
| 1398 }); |
| 1399 } else { |
| 1400 Sk4px::MapDstSrcAlpha(n, dst, src, aa, |
| 1401 [&](const Sk4px& dst4, const Sk4px& src4, const Sk16b& alpha
) { |
| 1402 // We can't exploit kFoldCoverageIntoSrcAlpha. That requires >=2
4-bit intermediates. |
| 1403 Sk4px res4 = ProcType::Xfer(src4, dst4); |
| 1404 return Sk4px::Wide(res4.mulWiden(alpha) + dst4.mulWiden(Sk16b(25
5)-alpha)) |
| 1405 .div255RoundNarrow(); |
| 1406 }); |
| 1407 } |
| 1408 } |
| 1409 |
| 1410 private: |
| 1411 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} |
| 1412 |
| 1413 typedef SkProcCoeffXfermode INHERITED; |
| 1414 }; |
| 1373 #endif | 1415 #endif |
| 1374 | 1416 |
| 1375 /////////////////////////////////////////////////////////////////////////////// | 1417 /////////////////////////////////////////////////////////////////////////////// |
| 1376 | 1418 |
| 1377 class SkDstOutXfermode : public SkProcCoeffXfermode { | 1419 class SkDstOutXfermode : public SkProcCoeffXfermode { |
| 1378 public: | 1420 public: |
| 1379 static SkDstOutXfermode* Create(const ProcCoeff& rec) { | 1421 static SkDstOutXfermode* Create(const ProcCoeff& rec) { |
| 1380 return SkNEW_ARGS(SkDstOutXfermode, (rec)); | 1422 return SkNEW_ARGS(SkDstOutXfermode, (rec)); |
| 1381 } | 1423 } |
| 1382 | 1424 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1438 switch (mode) { | 1480 switch (mode) { |
| 1439 case SkXfermode::kSrcATop_Mode: | 1481 case SkXfermode::kSrcATop_Mode: |
| 1440 xfer = SkT4fXfermode<SrcATop4f>::Create(rec); | 1482 xfer = SkT4fXfermode<SrcATop4f>::Create(rec); |
| 1441 break; | 1483 break; |
| 1442 case SkXfermode::kDstATop_Mode: | 1484 case SkXfermode::kDstATop_Mode: |
| 1443 xfer = SkT4fXfermode<DstATop4f>::Create(rec); | 1485 xfer = SkT4fXfermode<DstATop4f>::Create(rec); |
| 1444 break; | 1486 break; |
| 1445 case SkXfermode::kXor_Mode: | 1487 case SkXfermode::kXor_Mode: |
| 1446 xfer = SkT4fXfermode<Xor4f>::Create(rec); | 1488 xfer = SkT4fXfermode<Xor4f>::Create(rec); |
| 1447 break; | 1489 break; |
| 1490 #ifdef SK_PREFER_LEGACY_FLOAT_XFERMODES |
| 1448 case SkXfermode::kPlus_Mode: | 1491 case SkXfermode::kPlus_Mode: |
| 1449 xfer = SkT4fXfermode<Plus4f>::Create(rec); | 1492 xfer = SkT4fXfermode<Plus4f>::Create(rec); |
| 1450 break; | 1493 break; |
| 1451 case SkXfermode::kModulate_Mode: | 1494 case SkXfermode::kModulate_Mode: |
| 1452 xfer = SkT4fXfermode<Modulate4f>::Create(rec); | 1495 xfer = SkT4fXfermode<Modulate4f>::Create(rec); |
| 1453 break; | 1496 break; |
| 1454 case SkXfermode::kScreen_Mode: | 1497 case SkXfermode::kScreen_Mode: |
| 1455 xfer = SkT4fXfermode<Screen4f>::Create(rec); | 1498 xfer = SkT4fXfermode<Screen4f>::Create(rec); |
| 1456 break; | 1499 break; |
| 1500 #else |
| 1501 case SkXfermode::kPlus_Mode: |
| 1502 xfer = SkT4pxXfermode<Plus4f>::Create(rec); |
| 1503 break; |
| 1504 case SkXfermode::kModulate_Mode: |
| 1505 xfer = SkT4pxXfermode<Modulate4f>::Create(rec); |
| 1506 break; |
| 1507 case SkXfermode::kScreen_Mode: |
| 1508 xfer = SkT4pxXfermode<Screen4f>::Create(rec); |
| 1509 break; |
| 1510 #endif |
| 1457 case SkXfermode::kMultiply_Mode: | 1511 case SkXfermode::kMultiply_Mode: |
| 1458 xfer = SkT4fXfermode<Multiply4f>::Create(rec); | 1512 xfer = SkT4fXfermode<Multiply4f>::Create(rec); |
| 1459 break; | 1513 break; |
| 1460 case SkXfermode::kDifference_Mode: | 1514 case SkXfermode::kDifference_Mode: |
| 1461 xfer = SkT4fXfermode<Difference4f>::Create(rec); | 1515 xfer = SkT4fXfermode<Difference4f>::Create(rec); |
| 1462 break; | 1516 break; |
| 1463 case SkXfermode::kExclusion_Mode: | 1517 case SkXfermode::kExclusion_Mode: |
| 1464 xfer = SkT4fXfermode<Exclusion4f>::Create(rec); | 1518 xfer = SkT4fXfermode<Exclusion4f>::Create(rec); |
| 1465 break; | 1519 break; |
| 1466 default: | 1520 default: |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1762 } else { | 1816 } else { |
| 1763 proc16 = rec.fProc16_General; | 1817 proc16 = rec.fProc16_General; |
| 1764 } | 1818 } |
| 1765 } | 1819 } |
| 1766 return proc16; | 1820 return proc16; |
| 1767 } | 1821 } |
| 1768 | 1822 |
| 1769 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1823 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
| 1770 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1824 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
| 1771 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1825 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |