Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2010 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkGlyphCache_Globals_DEFINED
      9 #define SkGlyphCache_Globals_DEFINED
     10 
     11 #include "SkGlyphCache.h"
     12 #include "SkTLS.h"
     13 
     14 #ifndef SK_DEFAULT_FONT_CACHE_COUNT_LIMIT
     15     #define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT   2048
     16 #endif
     17 
     18 #ifndef SK_DEFAULT_FONT_CACHE_LIMIT
     19     #define SK_DEFAULT_FONT_CACHE_LIMIT     (2 * 1024 * 1024)
     20 #endif
     21 
     22 ///////////////////////////////////////////////////////////////////////////////
     23 
     24 class SkMutex;
     25 
     26 class SkGlyphCache_Globals {
     27 public:
     28     enum UseMutex {
     29         kNo_UseMutex,  // thread-local cache
     30         kYes_UseMutex  // shared cache
     31     };
     32 
     33     SkGlyphCache_Globals(UseMutex um) {
     34         fHead = NULL;
     35         fTotalMemoryUsed = 0;
     36         fCacheSizeLimit = SK_DEFAULT_FONT_CACHE_LIMIT;
     37         fCacheCount = 0;
     38         fCacheCountLimit = SK_DEFAULT_FONT_CACHE_COUNT_LIMIT;
     39 
     40         fMutex = (kYes_UseMutex == um) ? SkNEW(SkMutex) : NULL;
     41     }
     42 
     43     ~SkGlyphCache_Globals() {
     44         SkGlyphCache* cache = fHead;
     45         while (cache) {
     46             SkGlyphCache* next = cache->fNext;
     47             SkDELETE(cache);
     48             cache = next;
     49         }
     50 
     51         SkDELETE(fMutex);
     52     }
     53 
     54     SkMutex*        fMutex;
     55 
     56     SkGlyphCache* internalGetHead() const { return fHead; }
     57     SkGlyphCache* internalGetTail() const;
     58 
     59     size_t getTotalMemoryUsed() const { return fTotalMemoryUsed; }
     60     int getCacheCountUsed() const { return fCacheCount; }
     61 
     62 #ifdef SK_DEBUG
     63     void validate() const;
     64 #else
     65     void validate() const {}
     66 #endif
     67 
     68     int getCacheCountLimit() const { return fCacheCountLimit; }
     69     int setCacheCountLimit(int limit);
     70 
     71     size_t  getCacheSizeLimit() const { return fCacheSizeLimit; }
     72     size_t  setCacheSizeLimit(size_t limit);
     73 
     74     // returns true if this cache is over-budget either due to size limit
     75     // or count limit.
     76     bool isOverBudget() const {
     77         return fCacheCount > fCacheCountLimit ||
     78                fTotalMemoryUsed > fCacheSizeLimit;
     79     }
     80 
     81     void purgeAll(); // does not change budget
     82 
     83     // call when a glyphcache is available for caching (i.e. not in use)
     84     void attachCacheToHead(SkGlyphCache*);
     85 
     86     // can only be called when the mutex is already held
     87     void internalDetachCache(SkGlyphCache*);
     88     void internalAttachCacheToHead(SkGlyphCache*);
     89 
     90     // can return NULL
     91     static SkGlyphCache_Globals* FindTLS() {
     92         return (SkGlyphCache_Globals*)SkTLS::Find(CreateTLS);
     93     }
     94 
     95     static SkGlyphCache_Globals& GetTLS() {
     96         return *(SkGlyphCache_Globals*)SkTLS::Get(CreateTLS, DeleteTLS);
     97     }
     98 
     99     static void DeleteTLS() { SkTLS::Delete(CreateTLS); }
    100 
    101 private:
    102     SkGlyphCache* fHead;
    103     size_t  fTotalMemoryUsed;
    104     size_t  fCacheSizeLimit;
    105     int32_t fCacheCountLimit;
    106     int32_t fCacheCount;
    107 
    108     // Checkout budgets, modulated by the specified min-bytes-needed-to-purge,
    109     // and attempt to purge caches to match.
    110     // Returns number of bytes freed.
    111     size_t internalPurge(size_t minBytesNeeded = 0);
    112 
    113     static void* CreateTLS() {
    114         return SkNEW_ARGS(SkGlyphCache_Globals, (kNo_UseMutex));
    115     }
    116 
    117     static void DeleteTLS(void* ptr) {
    118         SkDELETE((SkGlyphCache_Globals*)ptr);
    119     }
    120 };
    121 
    122 #endif
    123