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 "SkXfermode_proccoeff.h" |
12 #include "SkColorPriv.h" | 12 #include "SkColorPriv.h" |
| 13 #include "SkMathPriv.h" |
| 14 #include "SkOnce.h" |
13 #include "SkReadBuffer.h" | 15 #include "SkReadBuffer.h" |
14 #include "SkWriteBuffer.h" | |
15 #include "SkMathPriv.h" | |
16 #include "SkString.h" | 16 #include "SkString.h" |
17 #include "SkUtilsArm.h" | 17 #include "SkUtilsArm.h" |
| 18 #include "SkWriteBuffer.h" |
18 | 19 |
19 #if !SK_ARM_NEON_IS_NONE | 20 #if !SK_ARM_NEON_IS_NONE |
20 #include "SkXfermode_opts_arm_neon.h" | 21 #include "SkXfermode_opts_arm_neon.h" |
21 #endif | 22 #endif |
22 | 23 |
23 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) | 24 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) |
24 | 25 |
25 #if 0 | 26 #if 0 |
26 // idea for higher precision blends in xfer procs (and slightly faster) | 27 // idea for higher precision blends in xfer procs (and slightly faster) |
27 // see DstATop as a probable caller | 28 // see DstATop as a probable caller |
(...skipping 1636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1664 | 1665 |
1665 #ifndef SK_IGNORE_TO_STRING | 1666 #ifndef SK_IGNORE_TO_STRING |
1666 void SkDstOutXfermode::toString(SkString* str) const { | 1667 void SkDstOutXfermode::toString(SkString* str) const { |
1667 this->INHERITED::toString(str); | 1668 this->INHERITED::toString(str); |
1668 } | 1669 } |
1669 #endif | 1670 #endif |
1670 | 1671 |
1671 /////////////////////////////////////////////////////////////////////////////// | 1672 /////////////////////////////////////////////////////////////////////////////// |
1672 | 1673 |
1673 SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex); | 1674 SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex); |
1674 static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1]; | 1675 static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1]; // All NULL to
start. |
| 1676 static bool gXfermodeCached[SK_ARRAY_COUNT(gCachedXfermodes)]; // All false to
start. |
1675 | 1677 |
1676 void SkXfermode::Term() { | 1678 void SkXfermode::Term() { |
1677 SkAutoMutexAcquire ac(gCachedXfermodesMutex); | 1679 SkAutoMutexAcquire ac(gCachedXfermodesMutex); |
1678 | 1680 |
1679 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { | 1681 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { |
1680 SkSafeUnref(gCachedXfermodes[i]); | 1682 SkSafeUnref(gCachedXfermodes[i]); |
1681 gCachedXfermodes[i] = NULL; | 1683 gCachedXfermodes[i] = NULL; |
1682 } | 1684 } |
1683 } | 1685 } |
1684 | 1686 |
1685 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, | 1687 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, |
1686 SkXfermode::Mode mode); | 1688 SkXfermode::Mode mode); |
1687 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); | 1689 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); |
1688 | 1690 |
| 1691 |
| 1692 static void create_mode(SkXfermode::Mode mode) { |
| 1693 SkASSERT(NULL == gCachedXfermodes[mode]); |
| 1694 |
| 1695 ProcCoeff rec = gProcCoeffs[mode]; |
| 1696 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); |
| 1697 if (pp != NULL) { |
| 1698 rec.fProc = pp; |
| 1699 } |
| 1700 |
| 1701 SkXfermode* xfer = NULL; |
| 1702 // check if we have a platform optim for that |
| 1703 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); |
| 1704 if (xfm != NULL) { |
| 1705 xfer = xfm; |
| 1706 } else { |
| 1707 // All modes can in theory be represented by the ProcCoeff rec, since |
| 1708 // it contains function ptrs. However, a few modes are both simple and |
| 1709 // commonly used, so we call those out for their own subclasses here. |
| 1710 switch (mode) { |
| 1711 case SkXfermode::kClear_Mode: |
| 1712 xfer = SkClearXfermode::Create(rec); |
| 1713 break; |
| 1714 case SkXfermode::kSrc_Mode: |
| 1715 xfer = SkSrcXfermode::Create(rec); |
| 1716 break; |
| 1717 case SkXfermode::kSrcOver_Mode: |
| 1718 SkASSERT(false); // should not land here |
| 1719 break; |
| 1720 case SkXfermode::kDstIn_Mode: |
| 1721 xfer = SkDstInXfermode::Create(rec); |
| 1722 break; |
| 1723 case SkXfermode::kDstOut_Mode: |
| 1724 xfer = SkDstOutXfermode::Create(rec); |
| 1725 break; |
| 1726 default: |
| 1727 // no special-case, just rely in the rec and its function-ptrs |
| 1728 xfer = SkProcCoeffXfermode::Create(rec, mode); |
| 1729 break; |
| 1730 } |
| 1731 } |
| 1732 gCachedXfermodes[mode] = xfer; |
| 1733 } |
| 1734 |
1689 SkXfermode* SkXfermode::Create(Mode mode) { | 1735 SkXfermode* SkXfermode::Create(Mode mode) { |
1690 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); | 1736 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
1691 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); | 1737 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); |
1692 | 1738 |
1693 if ((unsigned)mode >= kModeCount) { | 1739 if ((unsigned)mode >= kModeCount) { |
1694 // report error | 1740 // report error |
1695 return NULL; | 1741 return NULL; |
1696 } | 1742 } |
1697 | 1743 |
1698 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove
r | 1744 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove
r |
1699 // so we can just return NULL from the factory. | 1745 // so we can just return NULL from the factory. |
1700 if (kSrcOver_Mode == mode) { | 1746 if (kSrcOver_Mode == mode) { |
1701 return NULL; | 1747 return NULL; |
1702 } | 1748 } |
1703 | 1749 |
1704 // guard our access to gCachedXfermodes, since we may write into it | 1750 SkOnce(&gXfermodeCached[mode], &gCachedXfermodesMutex, create_mode, mode); |
1705 SkAutoMutexAcquire ac(gCachedXfermodesMutex); | |
1706 | |
1707 SkXfermode* xfer = gCachedXfermodes[mode]; | 1751 SkXfermode* xfer = gCachedXfermodes[mode]; |
1708 if (NULL == xfer) { | 1752 SkASSERT(xfer != NULL); |
1709 ProcCoeff rec = gProcCoeffs[mode]; | |
1710 | |
1711 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | |
1712 | |
1713 if (pp != NULL) { | |
1714 rec.fProc = pp; | |
1715 } | |
1716 | |
1717 // check if we have a platform optim for that | |
1718 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); | |
1719 if (xfm != NULL) { | |
1720 xfer = xfm; | |
1721 } else { | |
1722 // All modes can in theory be represented by the ProcCoeff rec, sinc
e | |
1723 // it contains function ptrs. However, a few modes are both simple a
nd | |
1724 // commonly used, so we call those out for their own subclasses here
. | |
1725 switch (mode) { | |
1726 case kClear_Mode: | |
1727 xfer = SkClearXfermode::Create(rec); | |
1728 break; | |
1729 case kSrc_Mode: | |
1730 xfer = SkSrcXfermode::Create(rec); | |
1731 break; | |
1732 case kSrcOver_Mode: | |
1733 SkASSERT(false); // should not land here | |
1734 break; | |
1735 case kDstIn_Mode: | |
1736 xfer = SkDstInXfermode::Create(rec); | |
1737 break; | |
1738 case kDstOut_Mode: | |
1739 xfer = SkDstOutXfermode::Create(rec); | |
1740 break; | |
1741 default: | |
1742 // no special-case, just rely in the rec and its function-pt
rs | |
1743 xfer = SkProcCoeffXfermode::Create(rec, mode); | |
1744 break; | |
1745 } | |
1746 } | |
1747 gCachedXfermodes[mode] = xfer; | |
1748 } | |
1749 return SkSafeRef(xfer); | 1753 return SkSafeRef(xfer); |
1750 } | 1754 } |
1751 | 1755 |
1752 SkXfermodeProc SkXfermode::GetProc(Mode mode) { | 1756 SkXfermodeProc SkXfermode::GetProc(Mode mode) { |
1753 SkXfermodeProc proc = NULL; | 1757 SkXfermodeProc proc = NULL; |
1754 if ((unsigned)mode < kModeCount) { | 1758 if ((unsigned)mode < kModeCount) { |
1755 proc = gProcCoeffs[mode].fProc; | 1759 proc = gProcCoeffs[mode].fProc; |
1756 } | 1760 } |
1757 return proc; | 1761 return proc; |
1758 } | 1762 } |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1983 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) | 1987 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) |
1984 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) | 1988 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) |
1985 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) | 1989 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode) |
1986 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) | 1990 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) |
1987 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) | 1991 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) |
1988 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) | 1992 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) |
1989 #if !SK_ARM_NEON_IS_NONE | 1993 #if !SK_ARM_NEON_IS_NONE |
1990 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode) | 1994 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode) |
1991 #endif | 1995 #endif |
1992 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1996 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |