Chromium Code Reviews| 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 |