Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/core/SkGlyphCache.cpp

Issue 1216983003: Move the GlyphCache to use a hash table instead of doing its own ad-hoc (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: address reeds comments Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/core/SkGlyphCache.h ('K') | « src/core/SkGlyphCache.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkLazyPtr.h" 11 #include "SkLazyPtr.h"
12 #include "SkMutex.h"
13 #include "SkPaint.h"
14 #include "SkPath.h" 12 #include "SkPath.h"
15 #include "SkTLS.h"
16 #include "SkTemplates.h" 13 #include "SkTemplates.h"
17 #include "SkTypeface.h" 14 #include "SkTypeface.h"
18 15
19 //#define SPEW_PURGE_STATUS 16 //#define SPEW_PURGE_STATUS
20 17
21 namespace { 18 namespace {
22 19
23 SkGlyphCache_Globals* create_globals() { 20 SkGlyphCache_Globals* create_globals() {
24 return SkNEW(SkGlyphCache_Globals); 21 return SkNEW(SkGlyphCache_Globals);
25 } 22 }
26 23
27 } // namespace 24 } // namespace
28 25
29 SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals); 26 SK_DECLARE_STATIC_LAZY_PTR(SkGlyphCache_Globals, globals, create_globals);
30 27
31 // Returns the shared globals 28 // Returns the shared globals
32 static SkGlyphCache_Globals& get_globals() { 29 static SkGlyphCache_Globals& get_globals() {
33 return *globals.get(); 30 return *globals.get();
34 } 31 }
35 32
36 /////////////////////////////////////////////////////////////////////////////// 33 ///////////////////////////////////////////////////////////////////////////////
37 34
38 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
39 #define RecordHashSuccess() fHashHitCount += 1
40 #define RecordHashCollisionIf(pred) do { if (pred) fHashMissCount += 1; } while (0)
41 #else
42 #define RecordHashSuccess() (void)0
43 #define RecordHashCollisionIf(pred) (void)0
44 #endif
45 #define RecordHashCollision() RecordHashCollisionIf(true)
46
47 ///////////////////////////////////////////////////////////////////////////////
48
49 // so we don't grow our arrays a lot 35 // so we don't grow our arrays a lot
50 #define kMinGlyphCount 16 36 #define kMinGlyphCount 16
51 #define kMinGlyphImageSize (16*2) 37 #define kMinGlyphImageSize (16*2)
52 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC ount) 38 #define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphC ount)
53 39
54 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca lerContext* ctx) 40 SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca lerContext* ctx)
55 : fScalerContext(ctx), fGlyphAlloc(kMinAllocAmount) { 41 : fDesc(desc->copy())
42 , fScalerContext(ctx)
43 , fGlyphAlloc(kMinAllocAmount) {
56 SkASSERT(typeface); 44 SkASSERT(typeface);
57 SkASSERT(desc); 45 SkASSERT(desc);
58 SkASSERT(ctx); 46 SkASSERT(ctx);
59 47
60 fPrev = fNext = NULL; 48 fPrev = fNext = NULL;
61 49
62 fDesc = desc->copy();
63 fScalerContext->getFontMetrics(&fFontMetrics); 50 fScalerContext->getFontMetrics(&fFontMetrics);
64 51
65 // Create the sentinel SkGlyph.
66 SkGlyph* sentinel = fGlyphArray.insert(0);
67 sentinel->initGlyphFromCombinedID(SkGlyph::kImpossibleID);
68
69 // Initialize all index to zero which points to the sentinel SkGlyph.
70 memset(fGlyphHash, 0x00, sizeof(fGlyphHash));
71
72 fMemoryUsed = sizeof(*this); 52 fMemoryUsed = sizeof(*this);
73 53
74 fGlyphArray.setReserve(kMinGlyphCount);
75
76 fAuxProcList = NULL; 54 fAuxProcList = NULL;
77
78 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
79 fHashHitCount = fHashMissCount = 0;
80 #endif
81 } 55 }
82 56
83 SkGlyphCache::~SkGlyphCache() { 57 SkGlyphCache::~SkGlyphCache() {
84 #if 0 58 fGlyphMap.foreach(
85 { 59 [](SkGlyph* g) {
86 size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); 60 if (g->fPath != NULL) {
mtklein 2015/07/21 19:35:52 Just FYI, SkDELETE does a null check, so this shou
herb_g 2015/07/21 22:27:34 Done.
87 size_t glyphAlloc = fGlyphAlloc.totalCapacity(); 61 SkDELETE(g->fPath);
88 size_t glyphHashUsed = 0;
89 size_t uniHashUsed = 0;
90 for (int i = 0; i < kHashCount; ++i) {
91 glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0;
92 uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharT oGlyphHash[0]) : 0;
93 }
94 size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph);
95 size_t imageUsed = 0;
96 for (int i = 0; i < fGlyphArray.count(); ++i) {
97 const SkGlyph& g = *fGlyphArray[i];
98 if (g.fImage) {
99 imageUsed += g.fHeight * g.rowBytes();
100 } 62 }
101 } 63 }
102 64 );
103 SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, gl yphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n ",
104 ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), g lyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed);
105
106 }
107 #endif
108 SkGlyph* gptr = fGlyphArray.begin();
109 SkGlyph* stop = fGlyphArray.end();
110 while (gptr < stop) {
111 SkPath* path = gptr->fPath;
112 if (path) {
113 SkDELETE(path);
114 }
115 gptr += 1;
116 }
117 SkDescriptor::Free(fDesc); 65 SkDescriptor::Free(fDesc);
118 SkDELETE(fScalerContext); 66 SkDELETE(fScalerContext);
119 this->invokeAndRemoveAuxProcs(); 67 this->invokeAndRemoveAuxProcs();
120 } 68 }
121 69
122 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { 70 SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(PackedUnicharID packed UnicharID) {
123 if (NULL == fCharToGlyphHash.get()) { 71 if (NULL == fPackedUnicharIDToPackedGlyphID.get()) {
124 // Allocate the array. 72 // Allocate the array.
125 fCharToGlyphHash.reset(kHashCount); 73 fPackedUnicharIDToPackedGlyphID.reset(kHashCount);
126 // Initialize entries of fCharToGlyphHash to index the sentinel glyph an d 74 // Initialize array to map character and position with the impossible gl yph ID. This
127 // an fID value that will not match any id. 75 // represents no mapping.
128 for (int i = 0; i <kHashCount; ++i) { 76 for (int i = 0; i <kHashCount; ++i) {
129 fCharToGlyphHash[i].fID = SkGlyph::kImpossibleID; 77 fPackedUnicharIDToPackedGlyphID[i].fPackedUnicharID = SkGlyph::kImpo ssibleID;
130 fCharToGlyphHash[i].fGlyphIndex = 0; 78 fPackedUnicharIDToPackedGlyphID[i].fPackedGlyphID = 0;
131 } 79 }
132 } 80 }
133 81
134 return &fCharToGlyphHash[ID2HashIndex(id)]; 82 return &fPackedUnicharIDToPackedGlyphID[SkChecksum::CheapMix(packedUnicharID ) & kHashMask];
135 }
136
137 void SkGlyphCache::adjustCaches(int insertion_index) {
138 for (int i = 0; i < kHashCount; ++i) {
139 if (fGlyphHash[i] >= SkToU16(insertion_index)) {
140 fGlyphHash[i] += 1;
141 }
142 }
143 if (fCharToGlyphHash.get() != NULL) {
144 for (int i = 0; i < kHashCount; ++i) {
145 if (fCharToGlyphHash[i].fGlyphIndex >= SkToU16(insertion_index)) {
146 fCharToGlyphHash[i].fGlyphIndex += 1;
147 }
148 }
149 }
150 } 83 }
151 84
152 /////////////////////////////////////////////////////////////////////////////// 85 ///////////////////////////////////////////////////////////////////////////////
153 86
154 #ifdef SK_DEBUG 87 #ifdef SK_DEBUG
155 #define VALIDATE() AutoValidate av(this) 88 #define VALIDATE() AutoValidate av(this)
156 #else 89 #else
157 #define VALIDATE() 90 #define VALIDATE()
158 #endif 91 #endif
159 92
160 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { 93 uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) {
161 VALIDATE(); 94 VALIDATE();
162 uint32_t id = SkGlyph::MakeID(charCode); 95 PackedUnicharID packedUnicharID = SkGlyph::MakeID(charCode);
163 const CharGlyphRec& rec = *this->getCharGlyphRec(id); 96 const CharGlyphRec& rec = *this->getCharGlyphRec(packedUnicharID);
164 97
165 if (rec.fID == id) { 98 if (rec.fPackedUnicharID == packedUnicharID) {
166 return fGlyphArray[rec.fGlyphIndex].getGlyphID(); 99 return SkGlyph::ID2Code(rec.fPackedGlyphID);
167 } else { 100 } else {
168 return fScalerContext->charToGlyphID(charCode); 101 return fScalerContext->charToGlyphID(charCode);
169 } 102 }
170 } 103 }
171 104
172 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) { 105 SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) {
173 return fScalerContext->glyphIDToChar(glyphID); 106 return fScalerContext->glyphIDToChar(glyphID);
174 } 107 }
175 108
176 unsigned SkGlyphCache::getGlyphCount() { 109 unsigned SkGlyphCache::getGlyphCount() {
177 return fScalerContext->getGlyphCount(); 110 return fScalerContext->getGlyphCount();
178 } 111 }
179 112
180 /////////////////////////////////////////////////////////////////////////////// 113 ///////////////////////////////////////////////////////////////////////////////
181 114
182 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) { 115 const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) {
183 VALIDATE(); 116 VALIDATE();
184 return *this->lookupByChar(charCode, kJustAdvance_MetricsType); 117 return *this->lookupByChar(charCode, kJustAdvance_MetricsType);
185 } 118 }
186 119
187 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) { 120 const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) {
188 VALIDATE(); 121 VALIDATE();
189 uint32_t id = SkGlyph::MakeID(glyphID); 122 PackedGlyphID packedGlyphID = SkGlyph::MakeID(glyphID);
190 return *this->lookupByCombinedID(id, kJustAdvance_MetricsType); 123 return *this->lookupByPackedGlyphID(packedGlyphID, kJustAdvance_MetricsType) ;
191 } 124 }
192 125
193 /////////////////////////////////////////////////////////////////////////////// 126 ///////////////////////////////////////////////////////////////////////////////
194 127
195 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) { 128 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) {
196 VALIDATE(); 129 VALIDATE();
197 return *this->lookupByChar(charCode, kFull_MetricsType); 130 return *this->lookupByChar(charCode, kFull_MetricsType);
198 } 131 }
199 132
200 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, 133 const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, SkFixed x, Sk Fixed y) {
201 SkFixed x, SkFixed y) {
202 VALIDATE(); 134 VALIDATE();
203 return *this->lookupByChar(charCode, kFull_MetricsType, x, y); 135 return *this->lookupByChar(charCode, kFull_MetricsType, x, y);
204 } 136 }
205 137
206 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) { 138 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) {
207 VALIDATE(); 139 VALIDATE();
208 uint32_t id = SkGlyph::MakeID(glyphID); 140 PackedGlyphID packedGlyphID = SkGlyph::MakeID(glyphID);
209 return *this->lookupByCombinedID(id, kFull_MetricsType); 141 return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType);
210 } 142 }
211 143
212 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) { 144 const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi xed y) {
213 VALIDATE(); 145 VALIDATE();
214 uint32_t id = SkGlyph::MakeID(glyphID, x, y); 146 PackedGlyphID packedGlyphID = SkGlyph::MakeID(glyphID, x, y);
215 return *this->lookupByCombinedID(id, kFull_MetricsType); 147 return *this->lookupByPackedGlyphID(packedGlyphID, kFull_MetricsType);
216 } 148 }
217 149
218 SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixe d x, SkFixed y) { 150 SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixe d x, SkFixed y) {
219 uint32_t id = SkGlyph::MakeID(charCode, x, y); 151 PackedUnicharID id = SkGlyph::MakeID(charCode, x, y);
220 CharGlyphRec* rec = this->getCharGlyphRec(id); 152 CharGlyphRec* rec = this->getCharGlyphRec(id);
221 SkGlyph* glyph; 153 if (rec->fPackedUnicharID != id) {
222 if (rec->fID != id) {
223 RecordHashCollisionIf(glyph_index != SkGlyph::kImpossibleID);
224 // this ID is based on the UniChar 154 // this ID is based on the UniChar
225 rec->fID = id; 155 rec->fPackedUnicharID = id;
226 // this ID is based on the glyph index 156 // this ID is based on the glyph index
227 id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); 157 PackedGlyphID combinedID = SkGlyph::MakeID(fScalerContext->charToGlyphID (charCode), x, y);
228 rec->fGlyphIndex = this->lookupMetrics(id, type); 158 rec->fPackedGlyphID = combinedID;
229 glyph = &fGlyphArray[rec->fGlyphIndex]; 159 return this->lookupByPackedGlyphID(combinedID, type);
230 } else { 160 } else {
231 RecordHashSuccess(); 161 return this->lookupByPackedGlyphID(rec->fPackedGlyphID, type);
232 glyph = &fGlyphArray[rec->fGlyphIndex];
233 if (type == kFull_MetricsType && glyph->isJustAdvance()) {
234 fScalerContext->getMetrics(glyph);
235 }
236 } 162 }
237 return glyph;
238 } 163 }
239 164
240 SkGlyph* SkGlyphCache::lookupByCombinedID(uint32_t id, MetricsType type) { 165 SkGlyph* SkGlyphCache::lookupByPackedGlyphID(PackedGlyphID packedGlyphID, Metric sType type) {
241 uint32_t hash_index = ID2HashIndex(id); 166 SkGlyph* glyph = fGlyphMap.find(packedGlyphID);
242 uint16_t glyph_index = fGlyphHash[hash_index];
243 SkGlyph* glyph = &fGlyphArray[glyph_index];
244 167
245 if (glyph->fID != id) { 168 if (NULL == glyph) {
246 RecordHashCollisionIf(glyph_index != SkGlyph::kImpossibleID); 169 glyph = this->allocateNewGlyph(packedGlyphID, type);
247 glyph_index = this->lookupMetrics(id, type);
248 fGlyphHash[hash_index] = glyph_index;
249 glyph = &fGlyphArray[glyph_index];
250 } else { 170 } else {
251 RecordHashSuccess();
252 if (type == kFull_MetricsType && glyph->isJustAdvance()) { 171 if (type == kFull_MetricsType && glyph->isJustAdvance()) {
253 fScalerContext->getMetrics(glyph); 172 fScalerContext->getMetrics(glyph);
254 } 173 }
255 } 174 }
256 return glyph; 175 return glyph;
257 } 176 }
258 177
259 uint16_t SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { 178 SkGlyph* SkGlyphCache::allocateNewGlyph(PackedGlyphID packedGlyphID, MetricsType mtype) {
260 SkASSERT(id != SkGlyph::kImpossibleID); 179 fMemoryUsed += sizeof(SkGlyph);
261 // Count is always greater than 0 because of the sentinel. 180
262 // The fGlyphArray cache is in descending order, so that the sentinel with a value of ~0 is 181 SkGlyph* glyphPtr;
263 // always at index 0. 182 {
264 SkGlyph* gptr = fGlyphArray.begin(); 183 SkGlyph glyph;
265 int lo = 0; 184 glyph.initGlyphFromCombinedID(packedGlyphID);
266 int hi = fGlyphArray.count() - 1; 185 glyphPtr = fGlyphMap.set(glyph);
267 while (lo < hi) {
268 int mid = (hi + lo) >> 1;
269 if (gptr[mid].fID > id) {
270 lo = mid + 1;
271 } else {
272 hi = mid;
273 }
274 } 186 }
275 187
276 uint16_t glyph_index = hi; 188 if (kJustAdvance_MetricsType == mtype) {
277 SkGlyph* glyph = &gptr[glyph_index]; 189 fScalerContext->getAdvance(glyphPtr);
278 if (glyph->fID == id) { 190 } else {
279 if (kFull_MetricsType == mtype && glyph->isJustAdvance()) { 191 SkASSERT(kFull_MetricsType == mtype);
280 fScalerContext->getMetrics(glyph); 192 fScalerContext->getMetrics(glyphPtr);
281 }
282 SkASSERT(glyph->fID != SkGlyph::kImpossibleID);
283 return glyph_index;
284 } 193 }
285 194
286 // check if we need to bump hi before falling though to the allocator 195 SkASSERT(glyphPtr->fID != SkGlyph::kImpossibleID);
287 if (glyph->fID > id) { 196 return glyphPtr;
288 glyph_index += 1;
289 }
290
291 // Not found, but hi contains the index of the insertion point of the new gl yph.
292 fMemoryUsed += sizeof(SkGlyph);
293
294 this->adjustCaches(glyph_index);
295
296 glyph = fGlyphArray.insert(glyph_index);
297 glyph->initGlyphFromCombinedID(id);
298
299 if (kJustAdvance_MetricsType == mtype) {
300 fScalerContext->getAdvance(glyph);
301 } else {
302 SkASSERT(kFull_MetricsType == mtype);
303 fScalerContext->getMetrics(glyph);
304 }
305
306 SkASSERT(glyph->fID != SkGlyph::kImpossibleID);
307 return glyph_index;
308 } 197 }
309 198
310 const void* SkGlyphCache::findImage(const SkGlyph& glyph) { 199 const void* SkGlyphCache::findImage(const SkGlyph& glyph) {
311 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) { 200 if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) {
312 if (NULL == glyph.fImage) { 201 if (NULL == glyph.fImage) {
313 size_t size = glyph.computeImageSize(); 202 size_t size = glyph.computeImageSize();
314 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size, 203 const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size,
315 SkChunkAlloc::kReturnNil_AllocFailType); 204 SkChunkAlloc::kReturnNil_AllocFailType);
316 // check that alloc() actually succeeded 205 // check that alloc() actually succeeded
317 if (glyph.fImage) { 206 if (glyph.fImage) {
(...skipping 29 matching lines...) Expand all
347 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize) ); 236 matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize) );
348 SkString name; 237 SkString name;
349 face->getFamilyName(&name); 238 face->getFamilyName(&name);
350 239
351 SkString msg; 240 SkString msg;
352 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:% d pntG:%d cntr:%d glyphs:%3d", 241 msg.printf("cache typeface:%x %25s:%d size:%2g [%g %g %g %g] lum:%02X devG:% d pntG:%d cntr:%d glyphs:%3d",
353 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize, 242 face->uniqueID(), name.c_str(), face->style(), rec.fTextSize,
354 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX], 243 matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX],
355 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY], 244 matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY],
356 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont rast, 245 rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fCont rast,
357 fGlyphArray.count()); 246 fGlyphMap.count());
358 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
359 const int sum = SkTMax(fHashHitCount + fHashMissCount, 1); // avoid divide -by-zero
360 msg.appendf(" hash:%2d\n", 100 * fHashHitCount / sum);
361 #endif
362 SkDebugf("%s\n", msg.c_str()); 247 SkDebugf("%s\n", msg.c_str());
363 } 248 }
364 249
365 /////////////////////////////////////////////////////////////////////////////// 250 ///////////////////////////////////////////////////////////////////////////////
366 251
367 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const { 252 bool SkGlyphCache::getAuxProcData(void (*proc)(void*), void** dataPtr) const {
368 const AuxProcRec* rec = fAuxProcList; 253 const AuxProcRec* rec = fAuxProcList;
369 while (rec) { 254 while (rec) {
370 if (rec->fProc == proc) { 255 if (rec->fProc == proc) {
371 if (dataPtr) { 256 if (dataPtr) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 void SkGlyphCache::Dump() { 407 void SkGlyphCache::Dump() {
523 SkGlyphCache_Globals& globals = get_globals(); 408 SkGlyphCache_Globals& globals = get_globals();
524 AutoAcquire ac(globals.fLock); 409 AutoAcquire ac(globals.fLock);
525 SkGlyphCache* cache; 410 SkGlyphCache* cache;
526 411
527 globals.validate(); 412 globals.validate();
528 413
529 SkDebugf("SkGlyphCache strikes:%d memory:%d\n", 414 SkDebugf("SkGlyphCache strikes:%d memory:%d\n",
530 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed()); 415 globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed());
531 416
532 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
533 int hitCount = 0;
534 int missCount = 0;
535 #endif
536
537 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) { 417 for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) {
538 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
539 hitCount += cache->fHashHitCount;
540 missCount += cache->fHashMissCount;
541 #endif
542 cache->dump(); 418 cache->dump();
543 } 419 }
544 #ifdef SK_GLYPHCACHE_TRACK_HASH_STATS
545 SkDebugf("Hash hit percent:%2d\n", 100 * hitCount / (hitCount + missCount));
546 #endif
547 } 420 }
548 421
549 /////////////////////////////////////////////////////////////////////////////// 422 ///////////////////////////////////////////////////////////////////////////////
550 423
551 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) { 424 void SkGlyphCache_Globals::attachCacheToHead(SkGlyphCache* cache) {
552 AutoAcquire ac(fLock); 425 AutoAcquire ac(fLock);
553 426
554 this->validate(); 427 this->validate();
555 cache->validate(); 428 cache->validate();
556 429
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 } 589 }
717 590
718 void SkGraphics::PurgeFontCache() { 591 void SkGraphics::PurgeFontCache() {
719 get_globals().purgeAll(); 592 get_globals().purgeAll();
720 SkTypefaceCache::PurgeAll(); 593 SkTypefaceCache::PurgeAll();
721 } 594 }
722 595
723 // TODO(herb): clean up TLS apis. 596 // TODO(herb): clean up TLS apis.
724 size_t SkGraphics::GetTLSFontCacheLimit() { return 0; } 597 size_t SkGraphics::GetTLSFontCacheLimit() { return 0; }
725 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { } 598 void SkGraphics::SetTLSFontCacheLimit(size_t bytes) { }
OLDNEW
« src/core/SkGlyphCache.h ('K') | « src/core/SkGlyphCache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698