diff options
-rw-r--r-- | include/core/SkPathRef.h | 2 | ||||
-rw-r--r-- | include/core/SkTypeface.h | 3 | ||||
-rw-r--r-- | include/ports/SkFontMgr.h | 2 | ||||
-rw-r--r-- | include/ports/SkFontMgr_indirect.h | 1 | ||||
-rw-r--r-- | include/ports/SkRemotableFontMgr.h | 2 | ||||
-rw-r--r-- | src/core/SkFontHost.cpp | 17 | ||||
-rwxr-xr-x | src/core/SkGlyphCache.cpp | 18 | ||||
-rw-r--r-- | src/core/SkLazyPtr.h | 2 | ||||
-rw-r--r-- | src/core/SkMatrix.cpp | 40 | ||||
-rw-r--r-- | src/core/SkMessageBus.h | 21 | ||||
-rw-r--r-- | src/core/SkPathRef.cpp | 16 | ||||
-rw-r--r-- | src/core/SkTypeface.cpp | 37 | ||||
-rw-r--r-- | src/fonts/SkRemotableFontMgr.cpp | 16 | ||||
-rw-r--r-- | src/lazy/SkDiscardableMemoryPool.cpp | 23 | ||||
-rw-r--r-- | src/ports/SkFontConfigInterface_direct.cpp | 15 |
15 files changed, 124 insertions, 91 deletions
diff --git a/include/core/SkPathRef.h b/include/core/SkPathRef.h index 47a69b7e73..8802714243 100644 --- a/include/core/SkPathRef.h +++ b/include/core/SkPathRef.h @@ -418,7 +418,7 @@ private: /** * Called the first time someone calls CreateEmpty to actually create the singleton. */ - static SkPathRef* CreateEmptyImpl(); + static void CreateEmptyImpl(int/*unused*/); void setIsOval(bool isOval) { fIsOval = isOval; } diff --git a/include/core/SkTypeface.h b/include/core/SkTypeface.h index 0b1c1f24ac..0be97eb4f7 100644 --- a/include/core/SkTypeface.h +++ b/include/core/SkTypeface.h @@ -339,8 +339,7 @@ private: uint32_t glyphIDsCount = 0) const; private: - static SkTypeface* CreateDefault(int style); // SkLazyPtr requires an int, not a Style. - static void DeleteDefault(SkTypeface*); + static void create_default_typeface(Style style); SkFontID fUniqueID; Style fStyle; diff --git a/include/ports/SkFontMgr.h b/include/ports/SkFontMgr.h index bb8c7b7d98..a2fad9aba6 100644 --- a/include/ports/SkFontMgr.h +++ b/include/ports/SkFontMgr.h @@ -131,7 +131,7 @@ protected: unsigned styleBits) const = 0; private: static SkFontMgr* Factory(); // implemented by porting layer - static SkFontMgr* CreateDefault(); + friend void set_up_default(SkFontMgr** singleton); typedef SkRefCnt INHERITED; }; diff --git a/include/ports/SkFontMgr_indirect.h b/include/ports/SkFontMgr_indirect.h index b9ce344a73..6d497ee4f8 100644 --- a/include/ports/SkFontMgr_indirect.h +++ b/include/ports/SkFontMgr_indirect.h @@ -11,6 +11,7 @@ #include "SkDataTable.h" #include "SkFontMgr.h" #include "SkFontStyle.h" +#include "SkOnce.h" #include "SkRemotableFontMgr.h" #include "SkTArray.h" #include "SkTypeface.h" diff --git a/include/ports/SkRemotableFontMgr.h b/include/ports/SkRemotableFontMgr.h index bd99497cda..68b4462206 100644 --- a/include/ports/SkRemotableFontMgr.h +++ b/include/ports/SkRemotableFontMgr.h @@ -46,7 +46,7 @@ public: private: SkRemotableFontIdentitySet() : fCount(0), fData() { } - static SkRemotableFontIdentitySet* NewEmptyImpl(); + static void NewEmptyImpl(int); int fCount; SkAutoTMalloc<SkFontIdentity> fData; diff --git a/src/core/SkFontHost.cpp b/src/core/SkFontHost.cpp index a16a8c42e0..9e7eeb182d 100644 --- a/src/core/SkFontHost.cpp +++ b/src/core/SkFontHost.cpp @@ -6,7 +6,7 @@ */ #include "SkFontLCDConfig.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" static SkFontLCDConfig::LCDOrientation gLCDOrientation = SkFontLCDConfig::kHorizontal_LCDOrientation; static SkFontLCDConfig::LCDOrder gLCDOrder = SkFontLCDConfig::kRGB_LCDOrder; @@ -198,14 +198,19 @@ SkTypeface* SkFontMgr::legacyCreateTypeface(const char familyName[], return this->onLegacyCreateTypeface(familyName, styleBits); } -SkFontMgr* SkFontMgr::CreateDefault() { - SkFontMgr* fm = SkFontMgr::Factory(); - return fm ? fm : SkNEW(SkEmptyFontMgr); +void set_up_default(SkFontMgr** singleton) { + *singleton = SkFontMgr::Factory(); + // we never want to return NULL + if (NULL == *singleton) { + *singleton = SkNEW(SkEmptyFontMgr); + } } SkFontMgr* SkFontMgr::RefDefault() { - SK_DECLARE_STATIC_LAZY_PTR(SkFontMgr, singleton, CreateDefault); - return SkRef(singleton.get()); + static SkFontMgr* gFM = NULL; + SK_DECLARE_STATIC_ONCE(once); + SkOnce(&once, set_up_default, &gFM); + return SkRef(gFM); } ////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index 2ab721aab4..699801d2db 100755 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -11,7 +11,7 @@ #include "SkGlyphCache_Globals.h" #include "SkDistanceFieldGen.h" #include "SkGraphics.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkPaint.h" #include "SkPath.h" #include "SkTemplates.h" @@ -21,18 +21,18 @@ //#define SPEW_PURGE_STATUS //#define RECORD_HASH_EFFICIENCY -namespace { - -SkGlyphCache_Globals* create_globals() { - return SkNEW_ARGS(SkGlyphCache_Globals, (SkGlyphCache_Globals::kYes_UseMutex)); +static void create_globals(SkGlyphCache_Globals** globals) { + *globals = SkNEW_ARGS(SkGlyphCache_Globals, (SkGlyphCache_Globals::kYes_UseMutex)); } -} // namespace - // Returns the shared globals static SkGlyphCache_Globals& getSharedGlobals() { - SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals); - return *globals.get(); + // we leak this, so we don't incur any shutdown cost of the destructor + static SkGlyphCache_Globals* gGlobals = NULL; + SK_DECLARE_STATIC_ONCE(once); + SkOnce(&once, create_globals, &gGlobals); + SkASSERT(NULL != gGlobals); + return *gGlobals; } // Returns the TLS globals (if set), or the shared globals diff --git a/src/core/SkLazyPtr.h b/src/core/SkLazyPtr.h index fa1a14e033..515086876c 100644 --- a/src/core/SkLazyPtr.h +++ b/src/core/SkLazyPtr.h @@ -64,6 +64,7 @@ // See FIXME below. class SkFontConfigInterface; +class SkTypeface; namespace Private { @@ -99,6 +100,7 @@ public: #ifdef SK_DEBUG // FIXME: We know we leak refs on some classes. For now, let them leak. void cleanup(SkFontConfigInterface*) {} + void cleanup(SkTypeface*) {} template <typename U> void cleanup(U* ptr) { Destroy(ptr); } ~SkLazyPtr() { diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp index 8778f78f41..40f6e5298d 100644 --- a/src/core/SkMatrix.cpp +++ b/src/core/SkMatrix.cpp @@ -7,7 +7,7 @@ #include "SkMatrix.h" #include "SkFloatBits.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkString.h" // In a few places, we performed the following @@ -1558,33 +1558,29 @@ bool SkMatrix::getMinMaxScales(SkScalar scaleFactors[2]) const { return get_scale_factor<kBoth_MinMaxOrBoth>(this->getType(), fMat, scaleFactors); } -namespace { - -SkMatrix* create_identity() { - SkMatrix* m = SkNEW(SkMatrix); - m->reset(); - return m; -} - -SkMatrix* create_invalid() { - SkMatrix* m = SkNEW(SkMatrix); - m->setAll(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, - SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, - SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); - m->getType(); // Force the type to be computed. - return m; +static void reset_identity_matrix(SkMatrix* identity) { + identity->reset(); } -} // namespace - const SkMatrix& SkMatrix::I() { - SK_DECLARE_STATIC_LAZY_PTR(SkMatrix, identity, create_identity); - return *identity.get(); + // If you can use C++11 now, you might consider replacing this with a constexpr constructor. + static SkMatrix gIdentity; + SK_DECLARE_STATIC_ONCE(once); + SkOnce(&once, reset_identity_matrix, &gIdentity); + return gIdentity; } const SkMatrix& SkMatrix::InvalidMatrix() { - SK_DECLARE_STATIC_LAZY_PTR(SkMatrix, invalid, create_invalid); - return *invalid.get(); + static SkMatrix gInvalid; + static bool gOnce; + if (!gOnce) { + gInvalid.setAll(SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, + SK_ScalarMax, SK_ScalarMax, SK_ScalarMax, + SK_ScalarMax, SK_ScalarMax, SK_ScalarMax); + gInvalid.getType(); // force the type to be computed + gOnce = true; + } + return gInvalid; } /////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/SkMessageBus.h b/src/core/SkMessageBus.h index f36c42b4c7..ddeac57ac1 100644 --- a/src/core/SkMessageBus.h +++ b/src/core/SkMessageBus.h @@ -8,7 +8,7 @@ #ifndef SkMessageBus_DEFINED #define SkMessageBus_DEFINED -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkTDArray.h" #include "SkThread.h" #include "SkTypes.h" @@ -38,7 +38,7 @@ public: private: SkMessageBus(); static SkMessageBus* Get(); - static SkMessageBus* New(); + static void New(SkMessageBus**); SkTDArray<Inbox*> fInboxes; SkMutex fInboxesMutex; @@ -46,11 +46,14 @@ private: // This must go in a single .cpp file, not some .h, or we risk creating more than one global // SkMessageBus per type when using shared libraries. -#define DECLARE_SKMESSAGEBUS_MESSAGE(Message) \ - template <> \ - SkMessageBus<Message>* SkMessageBus<Message>::Get() { \ - SK_DECLARE_STATIC_LAZY_PTR(SkMessageBus<Message>, bus, New); \ - return bus.get(); \ +#define DECLARE_SKMESSAGEBUS_MESSAGE(Message) \ + template <> \ + SkMessageBus<Message>* SkMessageBus<Message>::Get() { \ + static SkMessageBus<Message>* bus = NULL; \ + SK_DECLARE_STATIC_ONCE(once); \ + SkOnce(&once, &New, &bus); \ + SkASSERT(bus != NULL); \ + return bus; \ } // ----------------------- Implementation of SkMessageBus::Inbox ----------------------- @@ -97,8 +100,8 @@ template <typename Message> SkMessageBus<Message>::SkMessageBus() {} template <typename Message> -/*static*/ SkMessageBus<Message>* SkMessageBus<Message>::New() { - return SkNEW(SkMessageBus<Message>); +/*static*/ void SkMessageBus<Message>::New(SkMessageBus<Message>** bus) { + *bus = new SkMessageBus<Message>(); } template <typename Message> diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp index de7a8f56ae..161eb80419 100644 --- a/src/core/SkPathRef.cpp +++ b/src/core/SkPathRef.cpp @@ -6,7 +6,7 @@ */ #include "SkBuffer.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkPath.h" #include "SkPathRef.h" @@ -28,16 +28,18 @@ SkPathRef::Editor::Editor(SkAutoTUnref<SkPathRef>* pathRef, } ////////////////////////////////////////////////////////////////////////////// +static SkPathRef* gEmptyPathRef = NULL; +static void cleanup_gEmptyPathRef() { gEmptyPathRef->unref(); } -SkPathRef* SkPathRef::CreateEmptyImpl() { - SkPathRef* p = SkNEW(SkPathRef); - p->computeBounds(); // Preemptively avoid a race to clear fBoundsIsDirty. - return p; +void SkPathRef::CreateEmptyImpl(int) { + gEmptyPathRef = SkNEW(SkPathRef); + gEmptyPathRef->computeBounds(); // Preemptively avoid a race to clear fBoundsIsDirty. } SkPathRef* SkPathRef::CreateEmpty() { - SK_DECLARE_STATIC_LAZY_PTR(SkPathRef, empty, CreateEmptyImpl); - return SkRef(empty.get()); + SK_DECLARE_STATIC_ONCE(once); + SkOnce(&once, SkPathRef::CreateEmptyImpl, 0, cleanup_gEmptyPathRef); + return SkRef(gEmptyPathRef); } void SkPathRef::CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp index 6139c1e411..cd3953ba98 100644 --- a/src/core/SkTypeface.cpp +++ b/src/core/SkTypeface.cpp @@ -8,7 +8,7 @@ #include "SkAdvancedTypefaceMetrics.h" #include "SkFontDescriptor.h" #include "SkFontHost.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkStream.h" #include "SkTypeface.h" @@ -74,23 +74,34 @@ protected: } }; -SkTypeface* SkTypeface::CreateDefault(int style) { - SkTypeface* t = SkFontHost::CreateTypeface(NULL, NULL, (Style)style); - return t ? t : SkEmptyTypeface::Create(); -} +static SkTypeface* gDefaultTypefaces[] = { NULL, NULL, NULL, NULL }; +static const size_t FONT_STYLE_COUNT = SK_ARRAY_COUNT(gDefaultTypefaces); +static SkOnceFlag gDefaultTypefaceOnce[FONT_STYLE_COUNT] = { + SK_ONCE_INIT, SK_ONCE_INIT, SK_ONCE_INIT, SK_ONCE_INIT +}; +template <uintmax_t N> struct SkTIsPow2 { + static const bool value = (N & (N - 1)) == 0; +}; +SK_COMPILE_ASSERT(SkTIsPow2<FONT_STYLE_COUNT>::value, FONT_STYLE_COUNT_not_power_of_2); -void SkTypeface::DeleteDefault(SkTypeface* t) { - // The SkTypeface returned by SkFontHost::CreateTypeface may _itself_ be a - // cleverly-shared singleton. This is less than ideal. This means we - // cannot just assert our ownership and SkDELETE(t) like we'd want to. - SkSafeUnref(t); +void SkTypeface::create_default_typeface(Style style) { + if (NULL == gDefaultTypefaces[style]) { + gDefaultTypefaces[style] = SkFontHost::CreateTypeface(NULL, NULL, style); + } + if (NULL == gDefaultTypefaces[style]) { + // FIXME: Use a singleton for SkEmptyTypeface. + gDefaultTypefaces[style] = SkEmptyTypeface::Create(); + } } SkTypeface* SkTypeface::GetDefaultTypeface(Style style) { - SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkTypeface, defaults, 4, CreateDefault, DeleteDefault); + SkASSERT((size_t)style < FONT_STYLE_COUNT); + + // mask off any other bits to avoid a crash in SK_RELEASE + style = (Style)(style & (FONT_STYLE_COUNT - 1)); - SkASSERT((int)style < 4); - return defaults[style]; + SkOnce(&gDefaultTypefaceOnce[style], SkTypeface::create_default_typeface, style); + return gDefaultTypefaces[style]; } SkTypeface* SkTypeface::RefDefault(Style style) { diff --git a/src/fonts/SkRemotableFontMgr.cpp b/src/fonts/SkRemotableFontMgr.cpp index 633e91458b..1139972848 100644 --- a/src/fonts/SkRemotableFontMgr.cpp +++ b/src/fonts/SkRemotableFontMgr.cpp @@ -7,7 +7,7 @@ #include "SkRemotableFontMgr.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" SkRemotableFontIdentitySet::SkRemotableFontIdentitySet(int count, SkFontIdentity** data) : fCount(count), fData(count) @@ -16,11 +16,17 @@ SkRemotableFontIdentitySet::SkRemotableFontIdentitySet(int count, SkFontIdentity *data = fData; } -SkRemotableFontIdentitySet* SkRemotableFontIdentitySet::NewEmptyImpl() { - return SkNEW(SkRemotableFontIdentitySet); +static SkRemotableFontIdentitySet* gEmptyRemotableFontIdentitySet = NULL; +static void cleanup_gEmptyRemotableFontIdentitySet() { gEmptyRemotableFontIdentitySet->unref(); } + +void SkRemotableFontIdentitySet::NewEmptyImpl(int) { + gEmptyRemotableFontIdentitySet = new SkRemotableFontIdentitySet(); } SkRemotableFontIdentitySet* SkRemotableFontIdentitySet::NewEmpty() { - SK_DECLARE_STATIC_LAZY_PTR(SkRemotableFontIdentitySet, empty, NewEmptyImpl); - return SkRef(empty.get()); + SK_DECLARE_STATIC_ONCE(once); + SkOnce(&once, SkRemotableFontIdentitySet::NewEmptyImpl, 0, + cleanup_gEmptyRemotableFontIdentitySet); + gEmptyRemotableFontIdentitySet->ref(); + return gEmptyRemotableFontIdentitySet; } diff --git a/src/lazy/SkDiscardableMemoryPool.cpp b/src/lazy/SkDiscardableMemoryPool.cpp index 1d63a0bad7..4fb8ae4fe1 100644 --- a/src/lazy/SkDiscardableMemoryPool.cpp +++ b/src/lazy/SkDiscardableMemoryPool.cpp @@ -7,7 +7,7 @@ #include "SkDiscardableMemory.h" #include "SkDiscardableMemoryPool.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkTInternalLList.h" #include "SkThread.h" @@ -248,20 +248,27 @@ void DiscardableMemoryPool::dumpPool() { //////////////////////////////////////////////////////////////////////////////// SK_DECLARE_STATIC_MUTEX(gMutex); -SkDiscardableMemoryPool* create_global_pool() { - return SkDiscardableMemoryPool::Create(SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE, - &gMutex); +SkDiscardableMemoryPool* gPool = NULL; +void create_global_pool(int) { + SkASSERT(NULL == gPool); + gPool = SkDiscardableMemoryPool::Create( + SK_DEFAULT_GLOBAL_DISCARDABLE_MEMORY_POOL_SIZE, &gMutex); +} +void cleanup_global_pool() { + gPool->unref(); } - } // namespace -SkDiscardableMemoryPool* SkDiscardableMemoryPool::Create(size_t size, SkBaseMutex* mutex) { +SkDiscardableMemoryPool* SkDiscardableMemoryPool::Create( + size_t size, SkBaseMutex* mutex) { return SkNEW_ARGS(DiscardableMemoryPool, (size, mutex)); } SkDiscardableMemoryPool* SkGetGlobalDiscardableMemoryPool() { - SK_DECLARE_STATIC_LAZY_PTR(SkDiscardableMemoryPool, global, create_global_pool); - return global.get(); + SK_DECLARE_STATIC_ONCE(create_pool_once); + SkOnce(&create_pool_once, create_global_pool, 0, &cleanup_global_pool); + SkASSERT(NULL != gPool); + return gPool; } // defined in SkImageGenerator.h diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp index bc3dede40d..80ee56e85c 100644 --- a/src/ports/SkFontConfigInterface_direct.cpp +++ b/src/ports/SkFontConfigInterface_direct.cpp @@ -15,7 +15,7 @@ #include "SkBuffer.h" #include "SkFontConfigInterface.h" -#include "SkLazyPtr.h" +#include "SkOnce.h" #include "SkStream.h" size_t SkFontConfigInterface::FontIdentity::writeToMemory(void* addr) const { @@ -124,13 +124,14 @@ private: SkMutex mutex_; }; -namespace { -SkFontConfigInterface* create_direct() { return SkNEW(SkFontConfigInterfaceDirect); } -} // namespace - +static void create_singleton_direct_interface(SkFontConfigInterface** singleton) { + *singleton = new SkFontConfigInterfaceDirect; +} SkFontConfigInterface* SkFontConfigInterface::GetSingletonDirectInterface() { - SK_DECLARE_STATIC_LAZY_PTR(SkFontConfigInterface, direct, create_direct); - return direct.get(); + static SkFontConfigInterface* gDirect; + SK_DECLARE_STATIC_ONCE(once); + SkOnce(&once, create_singleton_direct_interface, &gDirect); + return gDirect; } /////////////////////////////////////////////////////////////////////////////// |