aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-07 19:12:04 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-07 19:12:04 +0000
commit09dcf754ff979dd30c3a1bd4443b54d99562fff0 (patch)
treed48271fdcff8e5b96dde58cefc3d8471aa5e35e1
parent2717d56b22f14ce0de206cd695ca2855bc568fbc (diff)
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
-rw-r--r--include/core/SkGraphics.h23
-rw-r--r--src/core/SkGlyphCache.cpp57
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);
+ }
+}
+