michael@0: /* michael@0: * Copyright 2010 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef SkGlyphCache_Globals_DEFINED michael@0: #define SkGlyphCache_Globals_DEFINED michael@0: michael@0: #include "SkGlyphCache.h" michael@0: #include "SkTLS.h" michael@0: michael@0: #ifndef SK_DEFAULT_FONT_CACHE_COUNT_LIMIT michael@0: #define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT 2048 michael@0: #endif michael@0: michael@0: #ifndef SK_DEFAULT_FONT_CACHE_LIMIT michael@0: #define SK_DEFAULT_FONT_CACHE_LIMIT (2 * 1024 * 1024) michael@0: #endif michael@0: michael@0: /////////////////////////////////////////////////////////////////////////////// michael@0: michael@0: class SkMutex; michael@0: michael@0: class SkGlyphCache_Globals { michael@0: public: michael@0: enum UseMutex { michael@0: kNo_UseMutex, // thread-local cache michael@0: kYes_UseMutex // shared cache michael@0: }; michael@0: michael@0: SkGlyphCache_Globals(UseMutex um) { michael@0: fHead = NULL; michael@0: fTotalMemoryUsed = 0; michael@0: fCacheSizeLimit = SK_DEFAULT_FONT_CACHE_LIMIT; michael@0: fCacheCount = 0; michael@0: fCacheCountLimit = SK_DEFAULT_FONT_CACHE_COUNT_LIMIT; michael@0: michael@0: fMutex = (kYes_UseMutex == um) ? SkNEW(SkMutex) : NULL; michael@0: } michael@0: michael@0: ~SkGlyphCache_Globals() { michael@0: SkGlyphCache* cache = fHead; michael@0: while (cache) { michael@0: SkGlyphCache* next = cache->fNext; michael@0: SkDELETE(cache); michael@0: cache = next; michael@0: } michael@0: michael@0: SkDELETE(fMutex); michael@0: } michael@0: michael@0: SkMutex* fMutex; michael@0: michael@0: SkGlyphCache* internalGetHead() const { return fHead; } michael@0: SkGlyphCache* internalGetTail() const; michael@0: michael@0: size_t getTotalMemoryUsed() const { return fTotalMemoryUsed; } michael@0: int getCacheCountUsed() const { return fCacheCount; } michael@0: michael@0: #ifdef SK_DEBUG michael@0: void validate() const; michael@0: #else michael@0: void validate() const {} michael@0: #endif michael@0: michael@0: int getCacheCountLimit() const { return fCacheCountLimit; } michael@0: int setCacheCountLimit(int limit); michael@0: michael@0: size_t getCacheSizeLimit() const { return fCacheSizeLimit; } michael@0: size_t setCacheSizeLimit(size_t limit); michael@0: michael@0: // returns true if this cache is over-budget either due to size limit michael@0: // or count limit. michael@0: bool isOverBudget() const { michael@0: return fCacheCount > fCacheCountLimit || michael@0: fTotalMemoryUsed > fCacheSizeLimit; michael@0: } michael@0: michael@0: void purgeAll(); // does not change budget michael@0: michael@0: // call when a glyphcache is available for caching (i.e. not in use) michael@0: void attachCacheToHead(SkGlyphCache*); michael@0: michael@0: // can only be called when the mutex is already held michael@0: void internalDetachCache(SkGlyphCache*); michael@0: void internalAttachCacheToHead(SkGlyphCache*); michael@0: michael@0: // can return NULL michael@0: static SkGlyphCache_Globals* FindTLS() { michael@0: return (SkGlyphCache_Globals*)SkTLS::Find(CreateTLS); michael@0: } michael@0: michael@0: static SkGlyphCache_Globals& GetTLS() { michael@0: return *(SkGlyphCache_Globals*)SkTLS::Get(CreateTLS, DeleteTLS); michael@0: } michael@0: michael@0: static void DeleteTLS() { SkTLS::Delete(CreateTLS); } michael@0: michael@0: private: michael@0: SkGlyphCache* fHead; michael@0: size_t fTotalMemoryUsed; michael@0: size_t fCacheSizeLimit; michael@0: int32_t fCacheCountLimit; michael@0: int32_t fCacheCount; michael@0: michael@0: // Checkout budgets, modulated by the specified min-bytes-needed-to-purge, michael@0: // and attempt to purge caches to match. michael@0: // Returns number of bytes freed. michael@0: size_t internalPurge(size_t minBytesNeeded = 0); michael@0: michael@0: static void* CreateTLS() { michael@0: return SkNEW_ARGS(SkGlyphCache_Globals, (kNo_UseMutex)); michael@0: } michael@0: michael@0: static void DeleteTLS(void* ptr) { michael@0: SkDELETE((SkGlyphCache_Globals*)ptr); michael@0: } michael@0: }; michael@0: michael@0: #endif