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