From 09dcf754ff979dd30c3a1bd4443b54d99562fff0 Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Mon, 7 May 2012 19:12:04 +0000 Subject: allow thread-local font cache Review URL: https://codereview.appspot.com/6101053 git-svn-id: http://skia.googlecode.com/svn/trunk@3857 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkGraphics.h | 23 +++++++++++++++++++ src/core/SkGlyphCache.cpp | 57 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/include/core/SkGraphics.h b/include/core/SkGraphics.h index 9e78dde5e4..3cfd70ffc2 100644 --- a/include/core/SkGraphics.h +++ b/include/core/SkGraphics.h @@ -65,6 +65,29 @@ public: */ static void SetFlags(const char* flags); + /** + * Return the max number of bytes that should be used by the thread-local + * font cache. + * If the cache needs to allocate more, it will purge previous entries. + * This max can be changed by calling SetFontCacheLimit(). + * + * If this thread has never called SetTLSFontCacheLimit, or has called it + * with 0, then this thread is using the shared font cache. In that case, + * this function will always return 0, and the caller may want to call + * GetFontCacheLimit. + */ + static size_t GetTLSFontCacheLimit(); + + /** + * Specify the max number of bytes that should be used by the thread-local + * font cache. If this value is zero (the default), then this thread will + * share the global font cache and its limit. + * + * This function returns the previous setting, as if GetFontCacheLimit() + * had be called before the new limit was set. + */ + static size_t SetTLSFontCacheLimit(size_t bytes); + private: /** This is automatically called by SkGraphics::Init(), and must be implemented by the host OS. This allows the host OS to register a callback diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp index b020f04411..76d8c21681 100644 --- a/src/core/SkGlyphCache.cpp +++ b/src/core/SkGlyphCache.cpp @@ -11,6 +11,7 @@ #include "SkGraphics.h" #include "SkPaint.h" #include "SkTemplates.h" +#include "SkTLS.h" //#define SPEW_PURGE_STATUS //#define USE_CACHE_HASH @@ -414,17 +415,27 @@ void SkGlyphCache::invokeAndRemoveAuxProcs() { class SkGlyphCache_Globals { public: - SkGlyphCache_Globals() { + enum UseMutex { + kNo_UseMutex, // thread-local cache + kYes_UseMutex, // shared cache + }; + + SkGlyphCache_Globals(UseMutex um) { fHead = NULL; fTotalMemoryUsed = 0; fFontCacheLimit = SK_DEFAULT_FONT_CACHE_LIMIT; + fMutex = (kYes_UseMutex == um) ? SkNEW(SkMutex) : NULL; #ifdef USE_CACHE_HASH sk_bzero(fHash, sizeof(fHash)); #endif } - SkMutex fMutex; + ~SkGlyphCache_Globals() { + SkDELETE(fMutex); + } + + SkMutex* fMutex; SkGlyphCache* fHead; size_t fTotalMemoryUsed; #ifdef USE_CACHE_HASH @@ -440,8 +451,27 @@ public: size_t getFontCacheLimit() const { return fFontCacheLimit; } size_t setFontCacheLimit(size_t limit); + // can return NULL + static SkGlyphCache_Globals* FindTLS() { + return (SkGlyphCache_Globals*)SkTLS::Find(CreateTLS); + } + + static SkGlyphCache_Globals& GetTLS() { + return *(SkGlyphCache_Globals*)SkTLS::Get(CreateTLS, DeleteTLS); + } + + static void DeleteTLS() { SkTLS::Delete(CreateTLS); } + private: size_t fFontCacheLimit; + + static void* CreateTLS() { + return SkNEW_ARGS(SkGlyphCache_Globals, (kNo_UseMutex)); + } + + static void DeleteTLS(void* ptr) { + SkDELETE((SkGlyphCache_Globals*)ptr); + } }; size_t SkGlyphCache_Globals::setFontCacheLimit(size_t newLimit) { @@ -455,9 +485,8 @@ size_t SkGlyphCache_Globals::setFontCacheLimit(size_t newLimit) { size_t currUsed = fTotalMemoryUsed; if (currUsed > newLimit) { - fMutex.acquire(); + SkAutoMutexAcquire ac(fMutex); SkGlyphCache::InternalFreeCache(this, currUsed - newLimit); - fMutex.release(); } return prevLimit; } @@ -465,14 +494,15 @@ size_t SkGlyphCache_Globals::setFontCacheLimit(size_t newLimit) { // Returns the shared globals static SkGlyphCache_Globals& getSharedGlobals() { // we leak this, so we don't incur any shutdown cost of the destructor - static SkGlyphCache_Globals* gGlobals = new SkGlyphCache_Globals; + static SkGlyphCache_Globals* gGlobals = SkNEW_ARGS(SkGlyphCache_Globals, + (SkGlyphCache_Globals::kYes_UseMutex)); return *gGlobals; } // Returns the TLS globals (if set), or the shared globals static SkGlyphCache_Globals& getGlobals() { - // TODO: Check TLS for local globals... - return getSharedGlobals(); + SkGlyphCache_Globals* tls = SkGlyphCache_Globals::FindTLS(); + return tls ? *tls : getSharedGlobals(); } void SkGlyphCache::VisitAllCaches(bool (*proc)(SkGlyphCache*, void*), @@ -698,3 +728,16 @@ void SkGraphics::PurgeFontCache() { SkTypefaceCache::PurgeAll(); } +size_t SkGraphics::GetTLSFontCacheLimit() { + const SkGlyphCache_Globals* tls = SkGlyphCache_Globals::FindTLS(); + return tls ? tls->getFontCacheLimit() : 0; +} + +size_t SkGraphics::SetTLSFontCacheLimit(size_t bytes) { + if (0 == bytes) { + SkGlyphCache_Globals::DeleteTLS(); + } else { + SkGlyphCache_Globals::GetTLS().setFontCacheLimit(bytes); + } +} + -- cgit v1.2.3