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 |