|
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 |