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