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 "SkMutex.h"
13 #include "SkSpinlock.h"
14 #include "SkTLS.h"
15 
16 #ifndef SK_DEFAULT_FONT_CACHE_COUNT_LIMIT
17     #define SK_DEFAULT_FONT_CACHE_COUNT_LIMIT   2048
18 #endif
19 
20 #ifndef SK_DEFAULT_FONT_CACHE_LIMIT
21     #define SK_DEFAULT_FONT_CACHE_LIMIT     (2 * 1024 * 1024)
22 #endif
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 
26 class SkGlyphCache_Globals {
27 public:
SkGlyphCache_Globals()28     SkGlyphCache_Globals() {
29         fHead = nullptr;
30         fTotalMemoryUsed = 0;
31         fCacheSizeLimit = SK_DEFAULT_FONT_CACHE_LIMIT;
32         fCacheCount = 0;
33         fCacheCountLimit = SK_DEFAULT_FONT_CACHE_COUNT_LIMIT;
34     }
35 
~SkGlyphCache_Globals()36     ~SkGlyphCache_Globals() {
37         SkGlyphCache* cache = fHead;
38         while (cache) {
39             SkGlyphCache* next = cache->fNext;
40             delete cache;
41             cache = next;
42         }
43     }
44 
45     SkSpinlock     fLock;
46 
internalGetHead()47     SkGlyphCache* internalGetHead() const { return fHead; }
48     SkGlyphCache* internalGetTail() const;
49 
getTotalMemoryUsed()50     size_t getTotalMemoryUsed() const { return fTotalMemoryUsed; }
getCacheCountUsed()51     int getCacheCountUsed() const { return fCacheCount; }
52 
53 #ifdef SK_DEBUG
54     void validate() const;
55 #else
validate()56     void validate() const {}
57 #endif
58 
getCacheCountLimit()59     int getCacheCountLimit() const { return fCacheCountLimit; }
60     int setCacheCountLimit(int limit);
61 
getCacheSizeLimit()62     size_t  getCacheSizeLimit() const { return fCacheSizeLimit; }
63     size_t  setCacheSizeLimit(size_t limit);
64 
65     // returns true if this cache is over-budget either due to size limit
66     // or count limit.
isOverBudget()67     bool isOverBudget() const {
68         return fCacheCount > fCacheCountLimit ||
69                fTotalMemoryUsed > fCacheSizeLimit;
70     }
71 
72     void purgeAll(); // does not change budget
73 
74     // call when a glyphcache is available for caching (i.e. not in use)
75     void attachCacheToHead(SkGlyphCache*);
76 
77     // can only be called when the mutex is already held
78     void internalDetachCache(SkGlyphCache*);
79     void internalAttachCacheToHead(SkGlyphCache*);
80 
81 private:
82     SkGlyphCache* fHead;
83     size_t  fTotalMemoryUsed;
84     size_t  fCacheSizeLimit;
85     int32_t fCacheCountLimit;
86     int32_t fCacheCount;
87 
88     // Checkout budgets, modulated by the specified min-bytes-needed-to-purge,
89     // and attempt to purge caches to match.
90     // Returns number of bytes freed.
91     size_t internalPurge(size_t minBytesNeeded = 0);
92 };
93 
94 #endif
95