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 | 9 |
10 #include "SkXfermode.h" | 10 #include "SkXfermode.h" |
11 #include "SkXfermode_proccoeff.h" | |
12 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
13 #include "SkFlattenableBuffers.h" | 12 #include "SkFlattenableBuffers.h" |
14 #include "SkMathPriv.h" | 13 #include "SkMathPriv.h" |
15 #include "SkString.h" | 14 #include "SkString.h" |
16 | 15 |
17 SK_DEFINE_INST_COUNT(SkXfermode) | 16 SK_DEFINE_INST_COUNT(SkXfermode) |
18 | 17 |
19 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) | 18 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) |
20 | 19 |
21 #if 0 | 20 #if 0 |
(...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 Db = 0; | 617 Db = 0; |
619 } | 618 } |
620 | 619 |
621 int a = srcover_byte(sa, da); | 620 int a = srcover_byte(sa, da); |
622 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); | 621 int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr); |
623 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); | 622 int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg); |
624 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); | 623 int b = blendfunc_nonsep_byte(sb, db, sa, da, Db); |
625 return SkPackARGB32(a, r, g, b); | 624 return SkPackARGB32(a, r, g, b); |
626 } | 625 } |
627 | 626 |
628 const ProcCoeff gProcCoeffs[] = { | 627 |
| 628 struct ProcCoeff { |
| 629 SkXfermodeProc fProc; |
| 630 SkXfermode::Coeff fSC; |
| 631 SkXfermode::Coeff fDC; |
| 632 }; |
| 633 |
| 634 #define CANNOT_USE_COEFF SkXfermode::Coeff(-1) |
| 635 |
| 636 static const ProcCoeff gProcCoeffs[] = { |
629 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, | 637 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff }, |
630 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, | 638 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff }, |
631 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, | 639 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff }, |
632 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, | 640 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff }, |
633 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, | 641 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff }, |
634 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, | 642 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff }, |
635 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, | 643 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff }, |
636 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, | 644 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff }, |
637 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, | 645 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff }, |
638 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, | 646 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff }, |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 | 1338 |
1331 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod
e::Mode>(mode), NULL))); | 1339 static AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermod
e::Mode>(mode), NULL))); |
1332 return CreateEffectRef(gEffect); | 1340 return CreateEffectRef(gEffect); |
1333 } | 1341 } |
1334 | 1342 |
1335 #endif | 1343 #endif |
1336 | 1344 |
1337 /////////////////////////////////////////////////////////////////////////////// | 1345 /////////////////////////////////////////////////////////////////////////////// |
1338 /////////////////////////////////////////////////////////////////////////////// | 1346 /////////////////////////////////////////////////////////////////////////////// |
1339 | 1347 |
1340 bool SkProcCoeffXfermode::asMode(Mode* mode) const { | 1348 class SkProcCoeffXfermode : public SkProcXfermode { |
1341 if (mode) { | 1349 public: |
1342 *mode = fMode; | 1350 SkProcCoeffXfermode(const ProcCoeff& rec, Mode mode) |
1343 } | 1351 : INHERITED(rec.fProc) { |
1344 return true; | 1352 fMode = mode; |
1345 } | 1353 // these may be valid, or may be CANNOT_USE_COEFF |
1346 | 1354 fSrcCoeff = rec.fSC; |
1347 bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const { | 1355 fDstCoeff = rec.fDC; |
1348 if (CANNOT_USE_COEFF == fSrcCoeff) { | |
1349 return false; | |
1350 } | 1356 } |
1351 | 1357 |
1352 if (sc) { | 1358 virtual bool asMode(Mode* mode) const SK_OVERRIDE { |
1353 *sc = fSrcCoeff; | 1359 if (mode) { |
1354 } | 1360 *mode = fMode; |
1355 if (dc) { | |
1356 *dc = fDstCoeff; | |
1357 } | |
1358 return true; | |
1359 } | |
1360 | |
1361 #if SK_SUPPORT_GPU | |
1362 bool SkProcCoeffXfermode::asNewEffectOrCoeff(GrContext*, | |
1363 GrEffectRef** effect, | |
1364 Coeff* src, | |
1365 Coeff* dst, | |
1366 GrTexture* background) const { | |
1367 if (this->asCoeff(src, dst)) { | |
1368 return true; | |
1369 } | |
1370 if (XferEffect::IsSupportedMode(fMode)) { | |
1371 if (NULL != effect) { | |
1372 *effect = XferEffect::Create(fMode, background); | |
1373 SkASSERT(NULL != *effect); | |
1374 } | 1361 } |
1375 return true; | 1362 return true; |
1376 } | 1363 } |
1377 return false; | 1364 |
1378 } | 1365 virtual bool asCoeff(Coeff* sc, Coeff* dc) const SK_OVERRIDE { |
| 1366 if (CANNOT_USE_COEFF == fSrcCoeff) { |
| 1367 return false; |
| 1368 } |
| 1369 |
| 1370 if (sc) { |
| 1371 *sc = fSrcCoeff; |
| 1372 } |
| 1373 if (dc) { |
| 1374 *dc = fDstCoeff; |
| 1375 } |
| 1376 return true; |
| 1377 } |
| 1378 |
| 1379 #if SK_SUPPORT_GPU |
| 1380 virtual bool asNewEffectOrCoeff(GrContext*, |
| 1381 GrEffectRef** effect, |
| 1382 Coeff* src, |
| 1383 Coeff* dst, |
| 1384 GrTexture* background) const SK_OVERRIDE { |
| 1385 if (this->asCoeff(src, dst)) { |
| 1386 return true; |
| 1387 } |
| 1388 if (XferEffect::IsSupportedMode(fMode)) { |
| 1389 if (NULL != effect) { |
| 1390 *effect = XferEffect::Create(fMode, background); |
| 1391 SkASSERT(NULL != *effect); |
| 1392 } |
| 1393 return true; |
| 1394 } |
| 1395 return false; |
| 1396 } |
1379 #endif | 1397 #endif |
1380 | 1398 |
1381 void SkProcCoeffXfermode::flatten(SkFlattenableWriteBuffer& buffer) const { | 1399 SK_DEVELOPER_TO_STRING() |
1382 this->INHERITED::flatten(buffer); | 1400 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode) |
1383 buffer.write32(fMode); | 1401 |
1384 } | 1402 protected: |
| 1403 SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { |
| 1404 fMode = (SkXfermode::Mode)buffer.read32(); |
| 1405 |
| 1406 const ProcCoeff& rec = gProcCoeffs[fMode]; |
| 1407 // these may be valid, or may be CANNOT_USE_COEFF |
| 1408 fSrcCoeff = rec.fSC; |
| 1409 fDstCoeff = rec.fDC; |
| 1410 // now update our function-ptr in the super class |
| 1411 this->INHERITED::setProc(rec.fProc); |
| 1412 } |
| 1413 |
| 1414 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { |
| 1415 this->INHERITED::flatten(buffer); |
| 1416 buffer.write32(fMode); |
| 1417 } |
| 1418 |
| 1419 private: |
| 1420 Mode fMode; |
| 1421 Coeff fSrcCoeff, fDstCoeff; |
| 1422 |
| 1423 typedef SkProcXfermode INHERITED; |
| 1424 }; |
1385 | 1425 |
1386 const char* SkXfermode::ModeName(Mode mode) { | 1426 const char* SkXfermode::ModeName(Mode mode) { |
1387 SkASSERT((unsigned) mode <= (unsigned)kLastMode); | 1427 SkASSERT((unsigned) mode <= (unsigned)kLastMode); |
1388 const char* gModeStrings[] = { | 1428 const char* gModeStrings[] = { |
1389 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", | 1429 "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn", |
1390 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", | 1430 "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus", |
1391 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", | 1431 "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", |
1392 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", | 1432 "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", |
1393 "Multiply", "Hue", "Saturation", "Color", "Luminosity" | 1433 "Multiply", "Hue", "Saturation", "Color", "Luminosity" |
1394 }; | 1434 }; |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1646 | 1686 |
1647 void SkXfermode::Term() { | 1687 void SkXfermode::Term() { |
1648 SkAutoMutexAcquire ac(gCachedXfermodesMutex); | 1688 SkAutoMutexAcquire ac(gCachedXfermodesMutex); |
1649 | 1689 |
1650 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { | 1690 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { |
1651 SkSafeUnref(gCachedXfermodes[i]); | 1691 SkSafeUnref(gCachedXfermodes[i]); |
1652 gCachedXfermodes[i] = NULL; | 1692 gCachedXfermodes[i] = NULL; |
1653 } | 1693 } |
1654 } | 1694 } |
1655 | 1695 |
1656 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, | |
1657 SkXfermode::Mode mode); | |
1658 | |
1659 SkXfermode* SkXfermode::Create(Mode mode) { | 1696 SkXfermode* SkXfermode::Create(Mode mode) { |
1660 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); | 1697 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
1661 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); | 1698 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); |
1662 | 1699 |
1663 if ((unsigned)mode >= kModeCount) { | 1700 if ((unsigned)mode >= kModeCount) { |
1664 // report error | 1701 // report error |
1665 return NULL; | 1702 return NULL; |
1666 } | 1703 } |
1667 | 1704 |
1668 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove
r | 1705 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove
r |
1669 // so we can just return NULL from the factory. | 1706 // so we can just return NULL from the factory. |
1670 if (kSrcOver_Mode == mode) { | 1707 if (kSrcOver_Mode == mode) { |
1671 return NULL; | 1708 return NULL; |
1672 } | 1709 } |
1673 | 1710 |
1674 // guard our access to gCachedXfermodes, since we may write into it | 1711 // guard our access to gCachedXfermodes, since we may write into it |
1675 SkAutoMutexAcquire ac(gCachedXfermodesMutex); | 1712 SkAutoMutexAcquire ac(gCachedXfermodesMutex); |
1676 | 1713 |
1677 SkXfermode* xfer = gCachedXfermodes[mode]; | 1714 SkXfermode* xfer = gCachedXfermodes[mode]; |
1678 if (NULL == xfer) { | 1715 if (NULL == xfer) { |
1679 const ProcCoeff& rec = gProcCoeffs[mode]; | 1716 const ProcCoeff& rec = gProcCoeffs[mode]; |
1680 | 1717 // All modes can in theory be represented by the ProcCoeff rec, since |
1681 // check if we have a platform optim for that | 1718 // it contains function ptrs. However, a few modes are both simple and |
1682 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); | 1719 // commonly used, so we call those out for their own subclasses here. |
1683 if (xfm != NULL) { | 1720 switch (mode) { |
1684 xfer = xfm; | 1721 case kClear_Mode: |
1685 } else { | 1722 xfer = SkNEW_ARGS(SkClearXfermode, (rec)); |
1686 // All modes can in theory be represented by the ProcCoeff rec, sinc
e | 1723 break; |
1687 // it contains function ptrs. However, a few modes are both simple a
nd | 1724 case kSrc_Mode: |
1688 // commonly used, so we call those out for their own subclasses here
. | 1725 xfer = SkNEW_ARGS(SkSrcXfermode, (rec)); |
1689 switch (mode) { | 1726 break; |
1690 case kClear_Mode: | 1727 case kSrcOver_Mode: |
1691 xfer = SkNEW_ARGS(SkClearXfermode, (rec)); | 1728 SkASSERT(false); // should not land here |
1692 break; | 1729 break; |
1693 case kSrc_Mode: | 1730 case kDstIn_Mode: |
1694 xfer = SkNEW_ARGS(SkSrcXfermode, (rec)); | 1731 xfer = SkNEW_ARGS(SkDstInXfermode, (rec)); |
1695 break; | 1732 break; |
1696 case kSrcOver_Mode: | 1733 case kDstOut_Mode: |
1697 SkASSERT(false); // should not land here | 1734 xfer = SkNEW_ARGS(SkDstOutXfermode, (rec)); |
1698 break; | 1735 break; |
1699 case kDstIn_Mode: | 1736 default: |
1700 xfer = SkNEW_ARGS(SkDstInXfermode, (rec)); | 1737 // no special-case, just rely in the rec and its function-ptrs |
1701 break; | 1738 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); |
1702 case kDstOut_Mode: | 1739 break; |
1703 xfer = SkNEW_ARGS(SkDstOutXfermode, (rec)); | |
1704 break; | |
1705 default: | |
1706 // no special-case, just rely in the rec and its function-pt
rs | |
1707 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode)); | |
1708 break; | |
1709 } | |
1710 } | 1740 } |
1711 gCachedXfermodes[mode] = xfer; | 1741 gCachedXfermodes[mode] = xfer; |
1712 } | 1742 } |
1713 return SkSafeRef(xfer); | 1743 return SkSafeRef(xfer); |
1714 } | 1744 } |
1715 | 1745 |
1716 SkXfermodeProc SkXfermode::GetProc(Mode mode) { | 1746 SkXfermodeProc SkXfermode::GetProc(Mode mode) { |
1717 SkXfermodeProc proc = NULL; | 1747 SkXfermodeProc proc = NULL; |
1718 if ((unsigned)mode < kModeCount) { | 1748 if ((unsigned)mode < kModeCount) { |
1719 proc = gProcCoeffs[mode].fProc; | 1749 proc = gProcCoeffs[mode].fProc; |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1944 return proc16; | 1974 return proc16; |
1945 } | 1975 } |
1946 | 1976 |
1947 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1977 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1948 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1978 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1949 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) | 1979 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) |
1950 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) | 1980 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) |
1951 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) | 1981 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) |
1952 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) | 1982 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) |
1953 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1983 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |