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_opts_SSE2.h" | 11 #include "SkXfermode_opts_SSE2.h" |
12 #include "SkXfermode_proccoeff.h" | 12 #include "SkXfermode_proccoeff.h" |
13 #include "SkColorPriv.h" | 13 #include "SkColorPriv.h" |
| 14 #include "SkLazyPtr.h" |
14 #include "SkMathPriv.h" | 15 #include "SkMathPriv.h" |
15 #include "SkOnce.h" | |
16 #include "SkReadBuffer.h" | 16 #include "SkReadBuffer.h" |
17 #include "SkString.h" | 17 #include "SkString.h" |
18 #include "SkUtilsArm.h" | 18 #include "SkUtilsArm.h" |
19 #include "SkWriteBuffer.h" | 19 #include "SkWriteBuffer.h" |
20 | 20 |
21 #if !SK_ARM_NEON_IS_NONE | 21 #if !SK_ARM_NEON_IS_NONE |
22 #include "SkXfermode_opts_arm_neon.h" | 22 #include "SkXfermode_opts_arm_neon.h" |
23 #endif | 23 #endif |
24 | 24 |
25 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) | 25 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b) |
(...skipping 1618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1644 } | 1644 } |
1645 | 1645 |
1646 #ifndef SK_IGNORE_TO_STRING | 1646 #ifndef SK_IGNORE_TO_STRING |
1647 void SkDstOutXfermode::toString(SkString* str) const { | 1647 void SkDstOutXfermode::toString(SkString* str) const { |
1648 this->INHERITED::toString(str); | 1648 this->INHERITED::toString(str); |
1649 } | 1649 } |
1650 #endif | 1650 #endif |
1651 | 1651 |
1652 /////////////////////////////////////////////////////////////////////////////// | 1652 /////////////////////////////////////////////////////////////////////////////// |
1653 | 1653 |
1654 SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex); | 1654 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXf
ermode::Mode mode); |
1655 static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1]; // All NULL to
start. | |
1656 static bool gXfermodeCached[SK_ARRAY_COUNT(gCachedXfermodes)]; // All false to
start. | |
1657 | |
1658 void SkXfermode::Term() { | |
1659 SkAutoMutexAcquire ac(gCachedXfermodesMutex); | |
1660 | |
1661 for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) { | |
1662 SkSafeUnref(gCachedXfermodes[i]); | |
1663 gCachedXfermodes[i] = NULL; | |
1664 } | |
1665 } | |
1666 | |
1667 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, | |
1668 SkXfermode::Mode mode); | |
1669 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); | 1655 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode); |
1670 | 1656 |
1671 | 1657 // Technically, can't be static and passed as a template parameter. So we use a
nonymous namespace. |
1672 static void create_mode(SkXfermode::Mode mode) { | 1658 namespace { |
1673 SkASSERT(NULL == gCachedXfermodes[mode]); | 1659 SkXfermode* create_mode(int iMode) { |
| 1660 SkXfermode::Mode mode = (SkXfermode::Mode)iMode; |
1674 | 1661 |
1675 ProcCoeff rec = gProcCoeffs[mode]; | 1662 ProcCoeff rec = gProcCoeffs[mode]; |
1676 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); | 1663 SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode); |
1677 if (pp != NULL) { | 1664 if (pp != NULL) { |
1678 rec.fProc = pp; | 1665 rec.fProc = pp; |
1679 } | 1666 } |
1680 | 1667 |
1681 SkXfermode* xfer = NULL; | 1668 SkXfermode* xfer = NULL; |
1682 // check if we have a platform optim for that | 1669 // check if we have a platform optim for that |
1683 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); | 1670 SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode); |
(...skipping 18 matching lines...) Expand all Loading... |
1702 break; | 1689 break; |
1703 case SkXfermode::kDstOut_Mode: | 1690 case SkXfermode::kDstOut_Mode: |
1704 xfer = SkDstOutXfermode::Create(rec); | 1691 xfer = SkDstOutXfermode::Create(rec); |
1705 break; | 1692 break; |
1706 default: | 1693 default: |
1707 // no special-case, just rely in the rec and its function-ptrs | 1694 // no special-case, just rely in the rec and its function-ptrs |
1708 xfer = SkProcCoeffXfermode::Create(rec, mode); | 1695 xfer = SkProcCoeffXfermode::Create(rec, mode); |
1709 break; | 1696 break; |
1710 } | 1697 } |
1711 } | 1698 } |
1712 gCachedXfermodes[mode] = xfer; | 1699 return xfer; |
1713 } | 1700 } |
| 1701 } // namespace |
| 1702 |
1714 | 1703 |
1715 SkXfermode* SkXfermode::Create(Mode mode) { | 1704 SkXfermode* SkXfermode::Create(Mode mode) { |
1716 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); | 1705 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount); |
1717 SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount); | |
1718 | 1706 |
1719 if ((unsigned)mode >= kModeCount) { | 1707 if ((unsigned)mode >= kModeCount) { |
1720 // report error | 1708 // report error |
1721 return NULL; | 1709 return NULL; |
1722 } | 1710 } |
1723 | 1711 |
1724 // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcove
r | 1712 // Skia's "default" mode is srcover. NULL in SkPaint is interpreted as srcov
er |
1725 // so we can just return NULL from the factory. | 1713 // so we can just return NULL from the factory. |
1726 if (kSrcOver_Mode == mode) { | 1714 if (kSrcOver_Mode == mode) { |
1727 return NULL; | 1715 return NULL; |
1728 } | 1716 } |
1729 | 1717 |
1730 SkOnce(&gXfermodeCached[mode], &gCachedXfermodesMutex, create_mode, mode); | 1718 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, kModeCount, create_mode
); |
1731 SkXfermode* xfer = gCachedXfermodes[mode]; | 1719 return SkSafeRef(cached[mode]); |
1732 SkASSERT(xfer != NULL); | |
1733 return SkSafeRef(xfer); | |
1734 } | 1720 } |
1735 | 1721 |
1736 SkXfermodeProc SkXfermode::GetProc(Mode mode) { | 1722 SkXfermodeProc SkXfermode::GetProc(Mode mode) { |
1737 SkXfermodeProc proc = NULL; | 1723 SkXfermodeProc proc = NULL; |
1738 if ((unsigned)mode < kModeCount) { | 1724 if ((unsigned)mode < kModeCount) { |
1739 proc = gProcCoeffs[mode].fProc; | 1725 proc = gProcCoeffs[mode].fProc; |
1740 } | 1726 } |
1741 return proc; | 1727 return proc; |
1742 } | 1728 } |
1743 | 1729 |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1970 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) | 1956 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode) |
1971 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) | 1957 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode) |
1972 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) | 1958 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode) |
1973 #if !SK_ARM_NEON_IS_NONE | 1959 #if !SK_ARM_NEON_IS_NONE |
1974 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode) | 1960 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode) |
1975 #endif | 1961 #endif |
1976 #if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS) | 1962 #if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS) |
1977 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSSE2ProcCoeffXfermode) | 1963 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSSE2ProcCoeffXfermode) |
1978 #endif | 1964 #endif |
1979 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1965 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |