Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: src/core/SkXfermode.cpp

Issue 215533002: SkOnce for SkXfermode::Create(Mode) (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: = NULL Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698