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