OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkGlyphCache.h" | 8 #include "SkGlyphCache.h" |
9 #include "SkGlyphCache_Globals.h" | 9 #include "SkGlyphCache_Globals.h" |
10 #include "SkGraphics.h" | 10 #include "SkGraphics.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 } | 33 } |
34 | 34 |
35 // Returns the TLS globals (if set), or the shared globals | 35 // Returns the TLS globals (if set), or the shared globals |
36 static SkGlyphCache_Globals& getGlobals() { | 36 static SkGlyphCache_Globals& getGlobals() { |
37 SkGlyphCache_Globals* tls = SkGlyphCache_Globals::FindTLS(); | 37 SkGlyphCache_Globals* tls = SkGlyphCache_Globals::FindTLS(); |
38 return tls ? *tls : getSharedGlobals(); | 38 return tls ? *tls : getSharedGlobals(); |
39 } | 39 } |
40 | 40 |
41 /////////////////////////////////////////////////////////////////////////////// | 41 /////////////////////////////////////////////////////////////////////////////// |
42 | 42 |
43 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
44 #define RecordHashSuccess() fHashHitCount += 1 | |
45 #define RecordHashCollisionIf(pred) do { if (pred) fHashMissCount += 1;
} while (0) | |
46 #else | |
47 #define RecordHashSuccess() (void)0 | |
48 #define RecordHashCollisionIf(pred) (void)0 | |
49 #endif | |
50 #define RecordHashCollision() RecordHashCollisionIf(true) | |
51 | |
52 /////////////////////////////////////////////////////////////////////////////// | |
53 | |
54 // so we don't grow our arrays a lot | 43 // so we don't grow our arrays a lot |
55 #define kMinGlyphCount 16 | 44 #define kMinGlyphCount 16 |
56 #define kMinGlyphImageSize (16*2) | 45 #define kMinGlyphImageSize (16*2) |
57 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC
ount) | 46 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC
ount) |
58 | 47 |
59 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
lerContext* ctx) | 48 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
lerContext* ctx) |
60 : fScalerContext(ctx), fGlyphAlloc(kMinAllocAmount) { | 49 : fScalerContext(ctx), fAlloc(kMinAllocAmount) { |
61 SkASSERT(typeface); | 50 SkASSERT(typeface); |
62 SkASSERT(desc); | 51 SkASSERT(desc); |
63 SkASSERT(ctx); | 52 SkASSERT(ctx); |
64 | 53 |
65 fPrev = fNext = NULL; | 54 fPrev = fNext = NULL; |
66 | 55 |
67 fDesc = desc->copy(); | 56 fDesc = desc->copy(); |
68 fScalerContext->getFontMetrics(&fFontMetrics); | 57 fScalerContext->getFontMetrics(&fFontMetrics); |
69 | 58 |
70 // init to 0 so that all of the pointers will be null | |
71 memset(fGlyphHash, 0, sizeof(fGlyphHash)); | |
72 | |
73 fMemoryUsed = sizeof(*this); | 59 fMemoryUsed = sizeof(*this); |
74 | 60 |
75 fGlyphArray.setReserve(kMinGlyphCount); | |
76 | |
77 fAuxProcList = NULL; | 61 fAuxProcList = NULL; |
78 | |
79 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
80 fHashHitCount = fHashMissCount = 0; | |
81 #endif | |
82 } | 62 } |
83 | 63 |
| 64 static void delete_path(uint32_t, SkGlyph* glyph) { SkDELETE(glyph->fPath); } |
| 65 |
84 SkGlyphCache::~SkGlyphCache() { | 66 SkGlyphCache::~SkGlyphCache() { |
85 #if 0 | 67 fGlyphs.foreach(delete_path); |
86 { | |
87 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); | |
88 size_t glyphAlloc = fGlyphAlloc.totalCapacity(); | |
89 size_t glyphHashUsed = 0; | |
90 size_t uniHashUsed = 0; | |
91 for (int i = 0; i < kHashCount; ++i) { | |
92 glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0; | |
93 uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharT
oGlyphHash[0]) : 0; | |
94 } | |
95 size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph); | |
96 size_t imageUsed = 0; | |
97 for (int i = 0; i < fGlyphArray.count(); ++i) { | |
98 const SkGlyph& g = *fGlyphArray[i]; | |
99 if (g.fImage) { | |
100 imageUsed += g.fHeight * g.rowBytes(); | |
101 } | |
102 } | |
103 | |
104 SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, gl
yphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n
", | |
105 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g
lyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed); | |
106 | |
107 } | |
108 #endif | |
109 SkGlyph** gptr = fGlyphArray.begin(); | |
110 SkGlyph** stop = fGlyphArray.end(); | |
111 while (gptr < stop) { | |
112 SkPath* path = (*gptr)->fPath; | |
113 if (path) { | |
114 SkDELETE(path); | |
115 } | |
116 gptr += 1; | |
117 } | |
118 SkDescriptor::Free(fDesc); | 68 SkDescriptor::Free(fDesc); |
119 SkDELETE(fScalerContext); | 69 SkDELETE(fScalerContext); |
120 this->invokeAndRemoveAuxProcs(); | 70 this->invokeAndRemoveAuxProcs(); |
121 } | 71 } |
122 | 72 |
123 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { | |
124 if (NULL == fCharToGlyphHash.get()) { | |
125 fCharToGlyphHash.reset(kHashCount); | |
126 // init with 0xFF so that the charCode field will be -1, which is invali
d | |
127 memset(fCharToGlyphHash.get(), 0xFF, | |
128 sizeof(CharGlyphRec) * kHashCount); | |
129 } | |
130 | |
131 return &fCharToGlyphHash[ID2HashIndex(id)]; | |
132 } | |
133 | |
134 /////////////////////////////////////////////////////////////////////////////// | 73 /////////////////////////////////////////////////////////////////////////////// |
135 | 74 |
136 #ifdef SK_DEBUG | 75 #ifdef SK_DEBUG |
137 #define VALIDATE() AutoValidate av(this) | 76 #define VALIDATE() AutoValidate av(this) |
138 #else | 77 #else |
139 #define VALIDATE() | 78 #define VALIDATE() |
140 #endif | 79 #endif |
141 | 80 |
142 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { | 81 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { |
143 VALIDATE(); | 82 VALIDATE(); |
144 uint32_t id = SkGlyph::MakeID(charCode); | 83 if (const uint16_t* glyphID = fCharToGlyphID.find(charCode)) { |
145 const CharGlyphRec& rec = *this->getCharGlyphRec(id); | 84 return *glyphID; |
146 | |
147 if (rec.fID == id) { | |
148 return rec.fGlyph->getGlyphID(); | |
149 } else { | |
150 return fScalerContext->charToGlyphID(charCode); | |
151 } | 85 } |
| 86 uint16_t glyphID = fScalerContext->charToGlyphID(charCode); |
| 87 fCharToGlyphID.set(charCode, glyphID); |
| 88 return glyphID; |
152 } | 89 } |
153 | 90 |
154 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { | 91 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { |
155 return fScalerContext->glyphIDToChar(glyphID); | 92 return fScalerContext->glyphIDToChar(glyphID); |
156 } | 93 } |
157 | 94 |
158 unsigned SkGlyphCache::getGlyphCount() { | 95 unsigned SkGlyphCache::getGlyphCount() { |
159 return fScalerContext->getGlyphCount(); | 96 return fScalerContext->getGlyphCount(); |
160 } | 97 } |
161 | 98 |
162 /////////////////////////////////////////////////////////////////////////////// | |
163 | |
164 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { | 99 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { |
165 VALIDATE(); | 100 return this->getGlyphIDAdvance(this->unicharToGlyph(charCode)); |
166 uint32_t id = SkGlyph::MakeID(charCode); | 101 } |
167 CharGlyphRec* rec = this->getCharGlyphRec(id); | 102 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { |
168 | 103 return this->getGlyphIDMetrics(this->unicharToGlyph(charCode)); |
169 if (rec->fID != id) { | 104 } |
170 // this ID is based on the UniChar | 105 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, SkFixed x, Sk
Fixed y) { |
171 rec->fID = id; | 106 return this->getGlyphIDMetrics(this->unicharToGlyph(charCode), x, y); |
172 // this ID is based on the glyph index | |
173 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode)); | |
174 rec->fGlyph = this->lookupMetrics(id, kJustAdvance_MetricsType); | |
175 } | |
176 return *rec->fGlyph; | |
177 } | 107 } |
178 | 108 |
179 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { | 109 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { |
180 VALIDATE(); | 110 VALIDATE(); |
181 uint32_t id = SkGlyph::MakeID(glyphID); | 111 const SkGlyph* glyph = |
182 unsigned index = ID2HashIndex(id); | 112 this->lookupMetrics(SkGlyph::MakeID(glyphID), kJustAdvance_MetricsType); |
183 SkGlyph* glyph = fGlyphHash[index]; | 113 SkASSERT(glyph); |
184 | |
185 if (NULL == glyph || glyph->fID != id) { | |
186 glyph = this->lookupMetrics(glyphID, kJustAdvance_MetricsType); | |
187 fGlyphHash[index] = glyph; | |
188 } | |
189 return *glyph; | 114 return *glyph; |
190 } | 115 } |
191 | 116 |
192 /////////////////////////////////////////////////////////////////////////////// | |
193 | |
194 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { | |
195 VALIDATE(); | |
196 uint32_t id = SkGlyph::MakeID(charCode); | |
197 CharGlyphRec* rec = this->getCharGlyphRec(id); | |
198 | |
199 if (rec->fID != id) { | |
200 RecordHashCollisionIf(rec->fGlyph != NULL); | |
201 // this ID is based on the UniChar | |
202 rec->fID = id; | |
203 // this ID is based on the glyph index | |
204 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode)); | |
205 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType); | |
206 } else { | |
207 RecordHashSuccess(); | |
208 if (rec->fGlyph->isJustAdvance()) { | |
209 fScalerContext->getMetrics(rec->fGlyph); | |
210 } | |
211 } | |
212 SkASSERT(rec->fGlyph->isFullMetrics()); | |
213 return *rec->fGlyph; | |
214 } | |
215 | |
216 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, | |
217 SkFixed x, SkFixed y) { | |
218 VALIDATE(); | |
219 uint32_t id = SkGlyph::MakeID(charCode, x, y); | |
220 CharGlyphRec* rec = this->getCharGlyphRec(id); | |
221 | |
222 if (rec->fID != id) { | |
223 RecordHashCollisionIf(rec->fGlyph != NULL); | |
224 // this ID is based on the UniChar | |
225 rec->fID = id; | |
226 // this ID is based on the glyph index | |
227 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); | |
228 rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType); | |
229 } else { | |
230 RecordHashSuccess(); | |
231 if (rec->fGlyph->isJustAdvance()) { | |
232 fScalerContext->getMetrics(rec->fGlyph); | |
233 } | |
234 } | |
235 SkASSERT(rec->fGlyph->isFullMetrics()); | |
236 return *rec->fGlyph; | |
237 } | |
238 | |
239 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { | 117 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { |
240 VALIDATE(); | 118 VALIDATE(); |
241 uint32_t id = SkGlyph::MakeID(glyphID); | 119 const SkGlyph* glyph = |
242 unsigned index = ID2HashIndex(id); | 120 this->lookupMetrics(SkGlyph::MakeID(glyphID), kFull_MetricsType); |
243 SkGlyph* glyph = fGlyphHash[index]; | 121 SkASSERT(glyph); |
244 | |
245 if (NULL == glyph || glyph->fID != id) { | |
246 RecordHashCollisionIf(glyph != NULL); | |
247 glyph = this->lookupMetrics(glyphID, kFull_MetricsType); | |
248 fGlyphHash[index] = glyph; | |
249 } else { | |
250 RecordHashSuccess(); | |
251 if (glyph->isJustAdvance()) { | |
252 fScalerContext->getMetrics(glyph); | |
253 } | |
254 } | |
255 SkASSERT(glyph->isFullMetrics()); | 122 SkASSERT(glyph->isFullMetrics()); |
256 return *glyph; | 123 return *glyph; |
257 } | 124 } |
258 | 125 |
259 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi
xed y) { | 126 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi
xed y) { |
260 VALIDATE(); | 127 VALIDATE(); |
261 uint32_t id = SkGlyph::MakeID(glyphID, x, y); | 128 const SkGlyph* glyph = |
262 unsigned index = ID2HashIndex(id); | 129 this->lookupMetrics(SkGlyph::MakeID(glyphID, x, y), kFull_MetricsType); |
263 SkGlyph* glyph = fGlyphHash[index]; | 130 SkASSERT(glyph); |
264 | |
265 if (NULL == glyph || glyph->fID != id) { | |
266 RecordHashCollisionIf(glyph != NULL); | |
267 glyph = this->lookupMetrics(id, kFull_MetricsType); | |
268 fGlyphHash[index] = glyph; | |
269 } else { | |
270 RecordHashSuccess(); | |
271 if (glyph->isJustAdvance()) { | |
272 fScalerContext->getMetrics(glyph); | |
273 } | |
274 } | |
275 SkASSERT(glyph->isFullMetrics()); | 131 SkASSERT(glyph->isFullMetrics()); |
276 return *glyph; | 132 return *glyph; |
277 } | 133 } |
278 | 134 |
279 SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { | 135 SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { |
280 SkGlyph* glyph; | 136 if (SkGlyph* glyph = fGlyphs.find(id)) { |
281 | 137 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) { |
282 int hi = 0; | 138 fScalerContext->getMetrics(glyph); |
283 int count = fGlyphArray.count(); | |
284 | |
285 if (count) { | |
286 SkGlyph** gptr = fGlyphArray.begin(); | |
287 int lo = 0; | |
288 | |
289 hi = count - 1; | |
290 while (lo < hi) { | |
291 int mid = (hi + lo) >> 1; | |
292 if (gptr[mid]->fID < id) { | |
293 lo = mid + 1; | |
294 } else { | |
295 hi = mid; | |
296 } | |
297 } | 139 } |
298 glyph = gptr[hi]; | 140 return glyph; |
299 if (glyph->fID == id) { | |
300 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) { | |
301 fScalerContext->getMetrics(glyph); | |
302 } | |
303 return glyph; | |
304 } | |
305 | |
306 // check if we need to bump hi before falling though to the allocator | |
307 if (glyph->fID < id) { | |
308 hi += 1; | |
309 } | |
310 } | 141 } |
311 | 142 |
312 // not found, but hi tells us where to inser the new glyph | 143 SkGlyph glyph; |
313 fMemoryUsed += sizeof(SkGlyph); | 144 glyph.init(id); |
314 | |
315 glyph = (SkGlyph*)fGlyphAlloc.alloc(sizeof(SkGlyph), | |
316 SkChunkAlloc::kThrow_AllocFailType); | |
317 glyph->init(id); | |
318 *fGlyphArray.insert(hi) = glyph; | |
319 | |
320 if (kJustAdvance_MetricsType == mtype) { | 145 if (kJustAdvance_MetricsType == mtype) { |
321 fScalerContext->getAdvance(glyph); | 146 fScalerContext->getAdvance(&glyph); |
322 } else { | 147 } else { |
323 SkASSERT(kFull_MetricsType == mtype); | 148 SkASSERT(kFull_MetricsType == mtype); |
324 fScalerContext->getMetrics(glyph); | 149 fScalerContext->getMetrics(&glyph); |
325 } | 150 } |
326 | 151 return fGlyphs.set(id, glyph); |
327 return glyph; | |
328 } | 152 } |
329 | 153 |
330 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { | 154 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { |
331 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { | 155 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { |
332 if (NULL == glyph.fImage) { | 156 if (NULL == glyph.fImage) { |
333 size_t size = glyph.computeImageSize(); | 157 size_t size = glyph.computeImageSize(); |
334 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, | 158 const_cast<SkGlyph&>(glyph).fImage = fAlloc.alloc(size, |
335 SkChunkAlloc::kReturnNil_AllocFailType); | 159 SkChunkAlloc::kReturnNil_AllocFailType); |
336 // check that alloc() actually succeeded | 160 // check that alloc() actually succeeded |
337 if (glyph.fImage) { | 161 if (glyph.fImage) { |
338 fScalerContext->getImage(glyph); | 162 fScalerContext->getImage(glyph); |
339 // TODO: the scaler may have changed the maskformat during | 163 // TODO: the scaler may have changed the maskformat during |
340 // getImage (e.g. from AA or LCD to BW) which means we may have | 164 // getImage (e.g. from AA or LCD to BW) which means we may have |
341 // overallocated the buffer. Check if the new computedImageSize | 165 // overallocated the buffer. Check if the new computedImageSize |
342 // is smaller, and if so, strink the alloc size in fImageAlloc. | 166 // is smaller, and if so, strink the alloc size in fImageAlloc. |
343 fMemoryUsed += size; | 167 fMemoryUsed += size; |
344 } | 168 } |
(...skipping 22 matching lines...) Expand all Loading... |
367 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize)
); | 191 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize)
); |
368 SkString name; | 192 SkString name; |
369 face->getFamilyName(&name); | 193 face->getFamilyName(&name); |
370 | 194 |
371 SkString msg; | 195 SkString msg; |
372 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:%
d pntG:%d cntr:%d glyphs:%3d", | 196 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:%
d pntG:%d cntr:%d glyphs:%3d", |
373 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize, | 197 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize, |
374 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX], | 198 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX], |
375 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY], | 199 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY], |
376 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont
rast, | 200 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont
rast, |
377 fGlyphArray.count()); | 201 fGlyphs.count()); |
378 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
379 const int sum = SkTMax(fHashHitCount + fHashMissCount, 1); // avoid divide
-by-zero | |
380 msg.appendf(" hash:%2d\n", 100 * fHashHitCount / sum); | |
381 #endif | |
382 SkDebugf("%s\n", msg.c_str()); | 202 SkDebugf("%s\n", msg.c_str()); |
383 } | 203 } |
384 | 204 |
385 /////////////////////////////////////////////////////////////////////////////// | 205 /////////////////////////////////////////////////////////////////////////////// |
386 | 206 |
387 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { | 207 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { |
388 const AuxProcRec* rec = fAuxProcList; | 208 const AuxProcRec* rec = fAuxProcList; |
389 while (rec) { | 209 while (rec) { |
390 if (rec->fProc == proc) { | 210 if (rec->fProc == proc) { |
391 if (dataPtr) { | 211 if (dataPtr) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 void SkGlyphCache::Dump() { | 361 void SkGlyphCache::Dump() { |
542 SkGlyphCache_Globals& globals = getGlobals(); | 362 SkGlyphCache_Globals& globals = getGlobals(); |
543 SkAutoMutexAcquire ac(globals.fMutex); | 363 SkAutoMutexAcquire ac(globals.fMutex); |
544 SkGlyphCache* cache; | 364 SkGlyphCache* cache; |
545 | 365 |
546 globals.validate(); | 366 globals.validate(); |
547 | 367 |
548 SkDebugf("SkGlyphCache strikes:%d memory:%d\n", | 368 SkDebugf("SkGlyphCache strikes:%d memory:%d\n", |
549 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed()); | 369 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed()); |
550 | 370 |
551 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
552 int hitCount = 0; | |
553 int missCount = 0; | |
554 #endif | |
555 | |
556 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext)
{ | 371 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext)
{ |
557 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
558 hitCount += cache->fHashHitCount; | |
559 missCount += cache->fHashMissCount; | |
560 #endif | |
561 cache->dump(); | 372 cache->dump(); |
562 } | 373 } |
563 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
564 SkDebugf("Hash hit percent:%2d\n", 100 * hitCount / (hitCount + missCount)); | |
565 #endif | |
566 } | 374 } |
567 | 375 |
568 /////////////////////////////////////////////////////////////////////////////// | 376 /////////////////////////////////////////////////////////////////////////////// |
569 | 377 |
570 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) { | 378 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) { |
571 SkAutoMutexAcquire ac(fMutex); | 379 SkAutoMutexAcquire ac(fMutex); |
572 | 380 |
573 this->validate(); | 381 this->validate(); |
574 cache->validate(); | 382 cache->validate(); |
575 | 383 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
667 cache->fNext->fPrev = cache->fPrev; | 475 cache->fNext->fPrev = cache->fPrev; |
668 } | 476 } |
669 cache->fPrev = cache->fNext = NULL; | 477 cache->fPrev = cache->fNext = NULL; |
670 } | 478 } |
671 | 479 |
672 /////////////////////////////////////////////////////////////////////////////// | 480 /////////////////////////////////////////////////////////////////////////////// |
673 | 481 |
674 #ifdef SK_DEBUG | 482 #ifdef SK_DEBUG |
675 | 483 |
676 void SkGlyphCache::validate() const { | 484 void SkGlyphCache::validate() const { |
677 #ifdef SK_DEBUG_GLYPH_CACHE | |
678 int count = fGlyphArray.count(); | |
679 for (int i = 0; i < count; i++) { | |
680 const SkGlyph* glyph = fGlyphArray[i]; | |
681 SkASSERT(glyph); | |
682 SkASSERT(fGlyphAlloc.contains(glyph)); | |
683 if (glyph->fImage) { | |
684 SkASSERT(fGlyphAlloc.contains(glyph->fImage)); | |
685 } | |
686 if (glyph->fDistanceField) { | |
687 SkASSERT(fGlyphAlloc.contains(glyph->fDistanceField)); | |
688 } | |
689 } | |
690 #endif | |
691 } | 485 } |
692 | 486 |
693 void SkGlyphCache_Globals::validate() const { | 487 void SkGlyphCache_Globals::validate() const { |
694 size_t computedBytes = 0; | 488 size_t computedBytes = 0; |
695 int computedCount = 0; | 489 int computedCount = 0; |
696 | 490 |
697 const SkGlyphCache* head = fHead; | 491 const SkGlyphCache* head = fHead; |
698 while (head != NULL) { | 492 while (head != NULL) { |
699 computedBytes += head->fMemoryUsed; | 493 computedBytes += head->fMemoryUsed; |
700 computedCount += 1; | 494 computedCount += 1; |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 return tls ? tls->getCacheSizeLimit() : 0; | 540 return tls ? tls->getCacheSizeLimit() : 0; |
747 } | 541 } |
748 | 542 |
749 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { | 543 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { |
750 if (0 == bytes) { | 544 if (0 == bytes) { |
751 SkGlyphCache_Globals::DeleteTLS(); | 545 SkGlyphCache_Globals::DeleteTLS(); |
752 } else { | 546 } else { |
753 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); | 547 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); |
754 } | 548 } |
755 } | 549 } |
OLD | NEW |