| 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 |