| 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 "Sk4px.h" |
| 13 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
| 14 #include "SkLazyPtr.h" | 14 #include "SkLazyPtr.h" |
| 15 #include "SkMathPriv.h" | 15 #include "SkMathPriv.h" |
| 16 #include "SkPMFloat.h" | 16 #include "SkPMFloat.h" |
| 17 #include "SkReadBuffer.h" | 17 #include "SkReadBuffer.h" |
| 18 #include "SkString.h" | 18 #include "SkString.h" |
| 19 #include "SkUtilsArm.h" | 19 #include "SkUtilsArm.h" |
| 20 #include "SkWriteBuffer.h" | 20 #include "SkWriteBuffer.h" |
| 21 | 21 |
| 22 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES | 22 // When implemented, the Sk4f and Sk4px xfermodes beat src/opts/SkXfermodes_opts
_SSE2's. |
| 23 // When implemented, the Sk4px, but not Sk4f, xfermodes beat src/opts/SkXfermode
s_arm_neon's. |
| 23 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 | 24 #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 |
| 24 /* | 25 #define SK_4F_XFERMODES_ARE_FAST |
| 25 * To be conservative, we only enable the new code path (using SkPMFloat) wh
en we | 26 #define SK_4PX_XFERMODES_ARE_FAST |
| 26 * "know" we're faster, which at the moment is only when we have SSE2 or bet
ter. | 27 #elif defined(SK_ARM_HAS_NEON) |
| 27 */ | 28 #define SK_4PX_XFERMODES_ARE_FAST |
| 28 #else | |
| 29 #define SK_SUPPORT_LEGACY_SCALAR_XFERMODES | |
| 30 #endif | |
| 31 #endif | 29 #endif |
| 32 | 30 |
| 33 #if !SK_ARM_NEON_IS_NONE | 31 #if !SK_ARM_NEON_IS_NONE |
| 34 #include "SkXfermode_opts_arm_neon.h" | 32 #include "SkXfermode_opts_arm_neon.h" |
| 35 #endif | 33 #endif |
| 36 | 34 |
| 37 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) | 35 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) |
| 38 | 36 |
| 39 static inline unsigned saturated_add(unsigned a, unsigned b) { | 37 static inline unsigned saturated_add(unsigned a, unsigned b) { |
| 40 SkASSERT(a <= 255); | 38 SkASSERT(a <= 255); |
| 41 SkASSERT(b <= 255); | 39 SkASSERT(b <= 255); |
| 42 unsigned sum = a + b; | 40 unsigned sum = a + b; |
| 43 if (sum > 255) { | 41 if (sum > 255) { |
| 44 sum = 255; | 42 sum = 255; |
| (...skipping 1144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1189 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, | 1187 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, |
| 1190 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, | 1188 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, |
| 1191 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, | 1189 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, |
| 1192 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, | 1190 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, |
| 1193 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, | 1191 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, |
| 1194 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, | 1192 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff }, |
| 1195 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, | 1193 { plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff }, |
| 1196 { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, | 1194 { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff }, |
| 1197 */ | 1195 */ |
| 1198 | 1196 |
| 1199 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES | |
| 1200 static const float gInv255 = 0.0039215683f; // (1.0f / 255) - ULP == SkBits2Flo
at(0x3B808080) | 1197 static const float gInv255 = 0.0039215683f; // (1.0f / 255) - ULP == SkBits2Flo
at(0x3B808080) |
| 1201 | 1198 |
| 1202 static Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) { | 1199 static Sk4f ramp(const Sk4f& v0, const Sk4f& v1, const Sk4f& t) { |
| 1203 return v0 + (v1 - v0) * t; | 1200 return v0 + (v1 - v0) * t; |
| 1204 } | 1201 } |
| 1205 | 1202 |
| 1206 static Sk4f clamp_255(const Sk4f& value) { | 1203 static Sk4f clamp_255(const Sk4f& value) { |
| 1207 return Sk4f::Min(Sk4f(255), value); | 1204 return Sk4f::Min(Sk4f(255), value); |
| 1208 } | 1205 } |
| 1209 | 1206 |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 .div255RoundNarrow(); | 1402 .div255RoundNarrow(); |
| 1406 }); | 1403 }); |
| 1407 } | 1404 } |
| 1408 } | 1405 } |
| 1409 | 1406 |
| 1410 private: | 1407 private: |
| 1411 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} | 1408 SkT4pxXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, ProcType::kM
ode) {} |
| 1412 | 1409 |
| 1413 typedef SkProcCoeffXfermode INHERITED; | 1410 typedef SkProcCoeffXfermode INHERITED; |
| 1414 }; | 1411 }; |
| 1415 #endif | |
| 1416 | 1412 |
| 1417 /////////////////////////////////////////////////////////////////////////////// | 1413 /////////////////////////////////////////////////////////////////////////////// |
| 1418 | 1414 |
| 1419 class SkDstOutXfermode : public SkProcCoeffXfermode { | 1415 class SkDstOutXfermode : public SkProcCoeffXfermode { |
| 1420 public: | 1416 public: |
| 1421 static SkDstOutXfermode* Create(const ProcCoeff& rec) { | 1417 static SkDstOutXfermode* Create(const ProcCoeff& rec) { |
| 1422 return SkNEW_ARGS(SkDstOutXfermode, (rec)); | 1418 return SkNEW_ARGS(SkDstOutXfermode, (rec)); |
| 1423 } | 1419 } |
| 1424 | 1420 |
| 1425 void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const overrid
e; | 1421 void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const overrid
e; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1467 namespace { | 1463 namespace { |
| 1468 SkXfermode* create_mode(int iMode) { | 1464 SkXfermode* create_mode(int iMode) { |
| 1469 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; | 1465 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; |
| 1470 | 1466 |
| 1471 ProcCoeff rec = gProcCoeffs[mode]; | 1467 ProcCoeff rec = gProcCoeffs[mode]; |
| 1472 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | 1468 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); |
| 1473 if (pp != NULL) { | 1469 if (pp != NULL) { |
| 1474 rec.fProc = pp; | 1470 rec.fProc = pp; |
| 1475 } | 1471 } |
| 1476 | 1472 |
| 1477 SkXfermode* xfer = NULL; | 1473 #if defined(SK_4PX_XFERMODES_ARE_FAST) && !defined(SK_PREFER_LEGACY_FLOAT_XFERMO
DES) |
| 1478 | |
| 1479 #ifndef SK_SUPPORT_LEGACY_SCALAR_XFERMODES | |
| 1480 switch (mode) { | 1474 switch (mode) { |
| 1481 case SkXfermode::kSrcATop_Mode: | 1475 case SkXfermode::kPlus_Mode: return SkT4pxXfermode<Plus4f>::Create(r
ec); |
| 1482 xfer = SkT4fXfermode<SrcATop4f>::Create(rec); | 1476 case SkXfermode::kModulate_Mode: return SkT4pxXfermode<Modulate4f>::Crea
te(rec); |
| 1483 break; | 1477 case SkXfermode::kScreen_Mode: return SkT4pxXfermode<Screen4f>::Create
(rec); |
| 1484 case SkXfermode::kDstATop_Mode: | 1478 default: break; |
| 1485 xfer = SkT4fXfermode<DstATop4f>::Create(rec); | |
| 1486 break; | |
| 1487 case SkXfermode::kXor_Mode: | |
| 1488 xfer = SkT4fXfermode<Xor4f>::Create(rec); | |
| 1489 break; | |
| 1490 #ifdef SK_PREFER_LEGACY_FLOAT_XFERMODES | |
| 1491 case SkXfermode::kPlus_Mode: | |
| 1492 xfer = SkT4fXfermode<Plus4f>::Create(rec); | |
| 1493 break; | |
| 1494 case SkXfermode::kModulate_Mode: | |
| 1495 xfer = SkT4fXfermode<Modulate4f>::Create(rec); | |
| 1496 break; | |
| 1497 case SkXfermode::kScreen_Mode: | |
| 1498 xfer = SkT4fXfermode<Screen4f>::Create(rec); | |
| 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 | |
| 1511 case SkXfermode::kMultiply_Mode: | |
| 1512 xfer = SkT4fXfermode<Multiply4f>::Create(rec); | |
| 1513 break; | |
| 1514 case SkXfermode::kDifference_Mode: | |
| 1515 xfer = SkT4fXfermode<Difference4f>::Create(rec); | |
| 1516 break; | |
| 1517 case SkXfermode::kExclusion_Mode: | |
| 1518 xfer = SkT4fXfermode<Exclusion4f>::Create(rec); | |
| 1519 break; | |
| 1520 default: | |
| 1521 break; | |
| 1522 } | |
| 1523 if (xfer) { | |
| 1524 return xfer; | |
| 1525 } | 1479 } |
| 1526 #endif | 1480 #endif |
| 1527 | 1481 |
| 1482 #if defined(SK_4F_XFERMODES_ARE_FAST) |
| 1483 switch (mode) { |
| 1484 case SkXfermode::kSrcATop_Mode: return SkT4fXfermode<SrcATop4f>::Crea
te(rec); |
| 1485 case SkXfermode::kDstATop_Mode: return SkT4fXfermode<DstATop4f>::Crea
te(rec); |
| 1486 case SkXfermode::kXor_Mode: return SkT4fXfermode<Xor4f>::Create(r
ec); |
| 1487 case SkXfermode::kPlus_Mode: return SkT4fXfermode<Plus4f>::Create(
rec); |
| 1488 case SkXfermode::kModulate_Mode: return SkT4fXfermode<Modulate4f>::Cre
ate(rec); |
| 1489 case SkXfermode::kScreen_Mode: return SkT4fXfermode<Screen4f>::Creat
e(rec); |
| 1490 case SkXfermode::kMultiply_Mode: return SkT4fXfermode<Multiply4f>::Cre
ate(rec); |
| 1491 case SkXfermode::kDifference_Mode: return SkT4fXfermode<Difference4f>::C
reate(rec); |
| 1492 case SkXfermode::kExclusion_Mode: return SkT4fXfermode<Exclusion4f>::Cr
eate(rec); |
| 1493 default: break; |
| 1494 } |
| 1495 #endif |
| 1496 |
| 1497 SkXfermode* xfer = NULL; |
| 1498 |
| 1528 // check if we have a platform optim for that | 1499 // check if we have a platform optim for that |
| 1529 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); | 1500 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); |
| 1530 if (xfm != NULL) { | 1501 if (xfm != NULL) { |
| 1531 xfer = xfm; | 1502 xfer = xfm; |
| 1532 } else { | 1503 } else { |
| 1533 // All modes can in theory be represented by the ProcCoeff rec, since | 1504 // All modes can in theory be represented by the ProcCoeff rec, since |
| 1534 // it contains function ptrs. However, a few modes are both simple and | 1505 // it contains function ptrs. However, a few modes are both simple and |
| 1535 // commonly used, so we call those out for their own subclasses here. | 1506 // commonly used, so we call those out for their own subclasses here. |
| 1536 switch (mode) { | 1507 switch (mode) { |
| 1537 case SkXfermode::kClear_Mode: | 1508 case SkXfermode::kClear_Mode: |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 } else { | 1787 } else { |
| 1817 proc16 = rec.fProc16_General; | 1788 proc16 = rec.fProc16_General; |
| 1818 } | 1789 } |
| 1819 } | 1790 } |
| 1820 return proc16; | 1791 return proc16; |
| 1821 } | 1792 } |
| 1822 | 1793 |
| 1823 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1794 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
| 1824 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1795 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
| 1825 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1796 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |