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), fGlyphAlloc(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 // Create the sentinel SkGlyph. | |
71 SkGlyph* sentinel = fGlyphArray.insert(0); | |
72 sentinel->initGlyphFromCombinedID(SkGlyph::kImpossibleID); | |
73 | |
74 // Initialize all index to zero which points to the sentinel SkGlyph. | |
75 memset(fGlyphHash, 0x00, sizeof(fGlyphHash)); | |
76 | |
77 fMemoryUsed = sizeof(*this); | 59 fMemoryUsed = sizeof(*this); |
78 | 60 |
79 fGlyphArray.setReserve(kMinGlyphCount); | |
80 | |
81 fAuxProcList = NULL; | 61 fAuxProcList = NULL; |
82 | |
83 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
84 fHashHitCount = fHashMissCount = 0; | |
85 #endif | |
86 } | 62 } |
87 | 63 |
88 SkGlyphCache::~SkGlyphCache() { | 64 SkGlyphCache::~SkGlyphCache() { |
89 #if 0 | 65 fGlyphMap.foreach([](SkGlyph* g) { if (g->fPath != NULL) { SkDELETE(g->fPath ); } } ); |
reed1
2015/07/06 17:29:35
perhaps we can add a LF or two, for readability?
herb_g
2015/07/20 22:21:44
Done.
| |
90 { | |
91 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); | |
92 size_t glyphAlloc = fGlyphAlloc.totalCapacity(); | |
93 size_t glyphHashUsed = 0; | |
94 size_t uniHashUsed = 0; | |
95 for (int i = 0; i < kHashCount; ++i) { | |
96 glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0; | |
97 uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharT oGlyphHash[0]) : 0; | |
98 } | |
99 size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph); | |
100 size_t imageUsed = 0; | |
101 for (int i = 0; i < fGlyphArray.count(); ++i) { | |
102 const SkGlyph& g = *fGlyphArray[i]; | |
103 if (g.fImage) { | |
104 imageUsed += g.fHeight * g.rowBytes(); | |
105 } | |
106 } | |
107 | |
108 SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, gl yphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n ", | |
109 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g lyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed); | |
110 | |
111 } | |
112 #endif | |
113 SkGlyph* gptr = fGlyphArray.begin(); | |
114 SkGlyph* stop = fGlyphArray.end(); | |
115 while (gptr < stop) { | |
116 SkPath* path = gptr->fPath; | |
117 if (path) { | |
118 SkDELETE(path); | |
119 } | |
120 gptr += 1; | |
121 } | |
122 SkDescriptor::Free(fDesc); | 66 SkDescriptor::Free(fDesc); |
123 SkDELETE(fScalerContext); | 67 SkDELETE(fScalerContext); |
124 this->invokeAndRemoveAuxProcs(); | 68 this->invokeAndRemoveAuxProcs(); |
125 } | 69 } |
126 | 70 |
127 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { | 71 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { |
128 if (NULL == fCharToGlyphHash.get()) { | 72 if (NULL == fCharToGlyphAndPositionIDHash.get()) { |
129 // Allocate the array. | 73 // Allocate the array. |
130 fCharToGlyphHash.reset(kHashCount); | 74 fCharToGlyphAndPositionIDHash.reset(kHashCount); |
131 // Initialize entries of fCharToGlyphHash to index the sentinel glyph an d | 75 // Initialize array to map character and position with the impossible gl yph ID. This |
132 // an fID value that will not match any id. | 76 // represents no mapping. |
133 for (int i = 0; i <kHashCount; ++i) { | 77 for (int i = 0; i <kHashCount; ++i) { |
134 fCharToGlyphHash[i].fID = SkGlyph::kImpossibleID; | 78 fCharToGlyphAndPositionIDHash[i].fID = SkGlyph::kImpossibleID; |
135 fCharToGlyphHash[i].fGlyphIndex = 0; | 79 fCharToGlyphAndPositionIDHash[i].fGlyphAndPositionID = 0; |
136 } | 80 } |
137 } | 81 } |
138 | 82 |
139 return &fCharToGlyphHash[ID2HashIndex(id)]; | 83 return &fCharToGlyphAndPositionIDHash[SkChecksum::CheapMix(id) & kHashMask]; |
140 } | |
141 | |
142 void SkGlyphCache::adjustCaches(int insertion_index) { | |
143 for (int i = 0; i < kHashCount; ++i) { | |
144 if (fGlyphHash[i] >= SkToU16(insertion_index)) { | |
145 fGlyphHash[i] += 1; | |
146 } | |
147 } | |
148 if (fCharToGlyphHash.get() != NULL) { | |
149 for (int i = 0; i < kHashCount; ++i) { | |
150 if (fCharToGlyphHash[i].fGlyphIndex >= SkToU16(insertion_index)) { | |
151 fCharToGlyphHash[i].fGlyphIndex += 1; | |
152 } | |
153 } | |
154 } | |
155 } | 84 } |
156 | 85 |
157 /////////////////////////////////////////////////////////////////////////////// | 86 /////////////////////////////////////////////////////////////////////////////// |
158 | 87 |
159 #ifdef SK_DEBUG | 88 #ifdef SK_DEBUG |
160 #define VALIDATE() AutoValidate av(this) | 89 #define VALIDATE() AutoValidate av(this) |
161 #else | 90 #else |
162 #define VALIDATE() | 91 #define VALIDATE() |
163 #endif | 92 #endif |
164 | 93 |
165 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { | 94 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { |
166 VALIDATE(); | 95 VALIDATE(); |
167 uint32_t id = SkGlyph::MakeID(charCode); | 96 uint32_t id = SkGlyph::MakeID(charCode); |
168 const CharGlyphRec& rec = *this->getCharGlyphRec(id); | 97 const CharGlyphRec& rec = *this->getCharGlyphRec(id); |
169 | 98 |
170 if (rec.fID == id) { | 99 if (rec.fID == id) { |
171 return fGlyphArray[rec.fGlyphIndex].getGlyphID(); | 100 return SkGlyph::ID2Code(rec.fGlyphAndPositionID); |
172 } else { | 101 } else { |
173 return fScalerContext->charToGlyphID(charCode); | 102 return fScalerContext->charToGlyphID(charCode); |
174 } | 103 } |
175 } | 104 } |
176 | 105 |
177 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { | 106 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { |
178 return fScalerContext->glyphIDToChar(glyphID); | 107 return fScalerContext->glyphIDToChar(glyphID); |
179 } | 108 } |
180 | 109 |
181 unsigned SkGlyphCache::getGlyphCount() { | 110 unsigned SkGlyphCache::getGlyphCount() { |
182 return fScalerContext->getGlyphCount(); | 111 return fScalerContext->getGlyphCount(); |
183 } | 112 } |
184 | 113 |
185 /////////////////////////////////////////////////////////////////////////////// | 114 /////////////////////////////////////////////////////////////////////////////// |
186 | 115 |
187 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { | 116 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { |
188 VALIDATE(); | 117 VALIDATE(); |
189 return *this->lookupByChar(charCode, kJustAdvance_MetricsType); | 118 return *this->lookupByChar(charCode, kJustAdvance_MetricsType); |
190 } | 119 } |
191 | 120 |
192 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { | 121 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { |
193 VALIDATE(); | 122 VALIDATE(); |
194 uint32_t id = SkGlyph::MakeID(glyphID); | 123 uint32_t glyphAndPositionID = SkGlyph::MakeID(glyphID); |
195 return *this->lookupByCombinedID(id, kJustAdvance_MetricsType); | 124 return *this->lookupByGlyphAndPositionID(glyphAndPositionID, kJustAdvance_Me tricsType); |
196 } | 125 } |
197 | 126 |
198 /////////////////////////////////////////////////////////////////////////////// | 127 /////////////////////////////////////////////////////////////////////////////// |
199 | 128 |
200 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { | 129 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { |
201 VALIDATE(); | 130 VALIDATE(); |
202 return *this->lookupByChar(charCode, kFull_MetricsType); | 131 return *this->lookupByChar(charCode, kFull_MetricsType); |
203 } | 132 } |
204 | 133 |
205 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, | 134 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, |
206 SkFixed x, SkFixed y) { | 135 SkFixed x, SkFixed y) { |
207 VALIDATE(); | 136 VALIDATE(); |
208 return *this->lookupByChar(charCode, kFull_MetricsType, x, y); | 137 return *this->lookupByChar(charCode, kFull_MetricsType, x, y); |
209 } | 138 } |
210 | 139 |
211 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { | 140 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { |
212 VALIDATE(); | 141 VALIDATE(); |
213 uint32_t id = SkGlyph::MakeID(glyphID); | 142 uint32_t glyphAndPositionID = SkGlyph::MakeID(glyphID); |
214 return *this->lookupByCombinedID(id, kFull_MetricsType); | 143 return *this->lookupByGlyphAndPositionID(glyphAndPositionID, kFull_MetricsTy pe); |
215 } | 144 } |
216 | 145 |
217 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) { | 146 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) { |
218 VALIDATE(); | 147 VALIDATE(); |
219 uint32_t id = SkGlyph::MakeID(glyphID, x, y); | 148 uint32_t glyphAndPositionID = SkGlyph::MakeID(glyphID, x, y); |
220 return *this->lookupByCombinedID(id, kFull_MetricsType); | 149 return *this->lookupByGlyphAndPositionID(glyphAndPositionID, kFull_MetricsTy pe); |
221 } | 150 } |
222 | 151 |
223 SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixe d x, SkFixed y) { | 152 SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixe d x, SkFixed y) { |
224 uint32_t id = SkGlyph::MakeID(charCode, x, y); | 153 uint32_t id = SkGlyph::MakeID(charCode, x, y); |
225 CharGlyphRec* rec = this->getCharGlyphRec(id); | 154 CharGlyphRec* rec = this->getCharGlyphRec(id); |
226 SkGlyph* glyph; | |
227 if (rec->fID != id) { | 155 if (rec->fID != id) { |
228 RecordHashCollisionIf(glyph_index != SkGlyph::kImpossibleID); | |
229 // this ID is based on the UniChar | 156 // this ID is based on the UniChar |
230 rec->fID = id; | 157 rec->fID = id; |
231 // this ID is based on the glyph index | 158 // this ID is based on the glyph index |
232 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); | 159 uint32_t combinedID = SkGlyph::MakeID(fScalerContext->charToGlyphID(char Code), x, y); |
233 rec->fGlyphIndex = this->lookupMetrics(id, type); | 160 rec->fGlyphAndPositionID = combinedID; |
234 glyph = &fGlyphArray[rec->fGlyphIndex]; | 161 return this->lookupByGlyphAndPositionID(combinedID, type); |
235 } else { | 162 } else { |
236 RecordHashSuccess(); | 163 return this->lookupByGlyphAndPositionID(rec->fGlyphAndPositionID, type); |
237 glyph = &fGlyphArray[rec->fGlyphIndex]; | |
238 if (type == kFull_MetricsType && glyph->isJustAdvance()) { | |
239 fScalerContext->getMetrics(glyph); | |
240 } | |
241 } | 164 } |
242 return glyph; | |
243 } | 165 } |
244 | 166 |
245 SkGlyph* SkGlyphCache::lookupByCombinedID(uint32_t id, MetricsType type) { | 167 SkGlyph* SkGlyphCache::lookupByGlyphAndPositionID(uint32_t glyphAndPositionID, M etricsType type) { |
246 uint32_t hash_index = ID2HashIndex(id); | 168 SkGlyph* glyph = fGlyphMap.find(glyphAndPositionID); |
247 uint16_t glyph_index = fGlyphHash[hash_index]; | |
248 SkGlyph* glyph = &fGlyphArray[glyph_index]; | |
249 | 169 |
250 if (glyph->fID != id) { | 170 if (NULL == glyph) { |
251 RecordHashCollisionIf(glyph_index != SkGlyph::kImpossibleID); | 171 glyph = this->allocateNewGlyph(glyphAndPositionID, type); |
252 glyph_index = this->lookupMetrics(id, type); | |
253 fGlyphHash[hash_index] = glyph_index; | |
254 glyph = &fGlyphArray[glyph_index]; | |
255 } else { | 172 } else { |
256 RecordHashSuccess(); | |
257 if (type == kFull_MetricsType && glyph->isJustAdvance()) { | 173 if (type == kFull_MetricsType && glyph->isJustAdvance()) { |
258 fScalerContext->getMetrics(glyph); | 174 fScalerContext->getMetrics(glyph); |
259 } | 175 } |
260 } | 176 } |
261 return glyph; | 177 return glyph; |
262 } | 178 } |
263 | 179 |
264 uint16_t SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { | 180 SkGlyph* SkGlyphCache::allocateNewGlyph(uint32_t glyphAndPositionID, MetricsType mtype) { |
265 SkASSERT(id != SkGlyph::kImpossibleID); | 181 fMemoryUsed += sizeof(SkGlyph); |
266 // Count is always greater than 0 because of the sentinel. | 182 |
267 // The fGlyphArray cache is in descending order, so that the sentinel with a value of ~0 is | 183 SkGlyph* glyphPtr; |
268 // always at index 0. | 184 { |
269 SkGlyph* gptr = fGlyphArray.begin(); | 185 SkGlyph glyph; |
270 int lo = 0; | 186 glyph.initGlyphFromCombinedID(glyphAndPositionID); |
271 int hi = fGlyphArray.count() - 1; | 187 glyphPtr = fGlyphMap.set(glyph); |
272 while (lo < hi) { | |
273 int mid = (hi + lo) >> 1; | |
274 if (gptr[mid].fID > id) { | |
275 lo = mid + 1; | |
276 } else { | |
277 hi = mid; | |
278 } | |
279 } | 188 } |
280 | 189 |
281 uint16_t glyph_index = hi; | 190 if (kJustAdvance_MetricsType == mtype) { |
282 SkGlyph* glyph = &gptr[glyph_index]; | 191 fScalerContext->getAdvance(glyphPtr); |
283 if (glyph->fID == id) { | 192 } else { |
284 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) { | 193 SkASSERT(kFull_MetricsType == mtype); |
285 fScalerContext->getMetrics(glyph); | 194 fScalerContext->getMetrics(glyphPtr); |
286 } | |
287 SkASSERT(glyph->fID != SkGlyph::kImpossibleID); | |
288 return glyph_index; | |
289 } | 195 } |
290 | 196 |
291 // check if we need to bump hi before falling though to the allocator | 197 SkASSERT(glyphPtr->fID != SkGlyph::kImpossibleID); |
292 if (glyph->fID > id) { | 198 return glyphPtr; |
293 glyph_index += 1; | |
294 } | |
295 | |
296 // Not found, but hi contains the index of the insertion point of the new gl yph. | |
297 fMemoryUsed += sizeof(SkGlyph); | |
298 | |
299 this->adjustCaches(glyph_index); | |
300 | |
301 glyph = fGlyphArray.insert(glyph_index); | |
302 glyph->initGlyphFromCombinedID(id); | |
303 | |
304 if (kJustAdvance_MetricsType == mtype) { | |
305 fScalerContext->getAdvance(glyph); | |
306 } else { | |
307 SkASSERT(kFull_MetricsType == mtype); | |
308 fScalerContext->getMetrics(glyph); | |
309 } | |
310 | |
311 SkASSERT(glyph->fID != SkGlyph::kImpossibleID); | |
312 return glyph_index; | |
313 } | 199 } |
314 | 200 |
315 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { | 201 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { |
316 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { | 202 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { |
317 if (NULL == glyph.fImage) { | 203 if (NULL == glyph.fImage) { |
318 size_t size = glyph.computeImageSize(); | 204 size_t size = glyph.computeImageSize(); |
319 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, | 205 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, |
320 SkChunkAlloc::kReturnNil_AllocFailType); | 206 SkChunkAlloc::kReturnNil_AllocFailType); |
321 // check that alloc() actually succeeded | 207 // check that alloc() actually succeeded |
322 if (glyph.fImage) { | 208 if (glyph.fImage) { |
(...skipping 29 matching lines...) Expand all Loading... | |
352 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize) ); | 238 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize) ); |
353 SkString name; | 239 SkString name; |
354 face->getFamilyName(&name); | 240 face->getFamilyName(&name); |
355 | 241 |
356 SkString msg; | 242 SkString msg; |
357 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:% d pntG:%d cntr:%d glyphs:%3d", | 243 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:% d pntG:%d cntr:%d glyphs:%3d", |
358 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize, | 244 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize, |
359 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX], | 245 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX], |
360 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY], | 246 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY], |
361 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont rast, | 247 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont rast, |
362 fGlyphArray.count()); | 248 fGlyphMap.count()); |
363 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
364 const int sum = SkTMax(fHashHitCount + fHashMissCount, 1); // avoid divide -by-zero | |
365 msg.appendf(" hash:%2d\n", 100 * fHashHitCount / sum); | |
366 #endif | |
367 SkDebugf("%s\n", msg.c_str()); | 249 SkDebugf("%s\n", msg.c_str()); |
368 } | 250 } |
369 | 251 |
370 /////////////////////////////////////////////////////////////////////////////// | 252 /////////////////////////////////////////////////////////////////////////////// |
371 | 253 |
372 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { | 254 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { |
373 const AuxProcRec* rec = fAuxProcList; | 255 const AuxProcRec* rec = fAuxProcList; |
374 while (rec) { | 256 while (rec) { |
375 if (rec->fProc == proc) { | 257 if (rec->fProc == proc) { |
376 if (dataPtr) { | 258 if (dataPtr) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 void SkGlyphCache::Dump() { | 408 void SkGlyphCache::Dump() { |
527 SkGlyphCache_Globals& globals = getGlobals(); | 409 SkGlyphCache_Globals& globals = getGlobals(); |
528 SkAutoMutexAcquire ac(globals.fMutex); | 410 SkAutoMutexAcquire ac(globals.fMutex); |
529 SkGlyphCache* cache; | 411 SkGlyphCache* cache; |
530 | 412 |
531 globals.validate(); | 413 globals.validate(); |
532 | 414 |
533 SkDebugf("SkGlyphCache strikes:%d memory:%d\n", | 415 SkDebugf("SkGlyphCache strikes:%d memory:%d\n", |
534 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed()); | 416 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed()); |
535 | 417 |
536 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
537 int hitCount = 0; | |
538 int missCount = 0; | |
539 #endif | |
540 | |
541 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) { | 418 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) { |
542 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
543 hitCount += cache->fHashHitCount; | |
544 missCount += cache->fHashMissCount; | |
545 #endif | |
546 cache->dump(); | 419 cache->dump(); |
547 } | 420 } |
548 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS | |
549 SkDebugf("Hash hit percent:%2d\n", 100 * hitCount / (hitCount + missCount)); | |
550 #endif | |
551 } | 421 } |
552 | 422 |
553 /////////////////////////////////////////////////////////////////////////////// | 423 /////////////////////////////////////////////////////////////////////////////// |
554 | 424 |
555 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) { | 425 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) { |
556 SkAutoMutexAcquire ac(fMutex); | 426 SkAutoMutexAcquire ac(fMutex); |
557 | 427 |
558 this->validate(); | 428 this->validate(); |
559 cache->validate(); | 429 cache->validate(); |
560 | 430 |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
727 return tls ? tls->getCacheSizeLimit() : 0; | 597 return tls ? tls->getCacheSizeLimit() : 0; |
728 } | 598 } |
729 | 599 |
730 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { | 600 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { |
731 if (0 == bytes) { | 601 if (0 == bytes) { |
732 SkGlyphCache_Globals::DeleteTLS(); | 602 SkGlyphCache_Globals::DeleteTLS(); |
733 } else { | 603 } else { |
734 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); | 604 SkGlyphCache_Globals::GetTLS().setCacheSizeLimit(bytes); |
735 } | 605 } |
736 } | 606 } |
OLD | NEW |