Index: src/core/SkGlyphCache.cpp |
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp |
index ec342275cc6f3c6354eb60d0c16eeebcb8d0767b..26e1a4bddc7b41ced6b42d7f962f8bf91bde6f61 100755 |
--- a/src/core/SkGlyphCache.cpp |
+++ b/src/core/SkGlyphCache.cpp |
@@ -40,17 +40,6 @@ static SkGlyphCache_Globals& getGlobals() { |
/////////////////////////////////////////////////////////////////////////////// |
-#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
- #define RecordHashSuccess() fHashHitCount += 1 |
- #define RecordHashCollisionIf(pred) do { if (pred) fHashMissCount += 1; } while (0) |
-#else |
- #define RecordHashSuccess() (void)0 |
- #define RecordHashCollisionIf(pred) (void)0 |
-#endif |
-#define RecordHashCollision() RecordHashCollisionIf(true) |
- |
-/////////////////////////////////////////////////////////////////////////////// |
- |
// so we don't grow our arrays a lot |
#define kMinGlyphCount 16 |
#define kMinGlyphImageSize (16*2) |
@@ -67,58 +56,13 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca |
fDesc = desc->copy(); |
fScalerContext->getFontMetrics(&fFontMetrics); |
- // Create the sentinel SkGlyph. |
- SkGlyph* sentinel = fGlyphArray.insert(0); |
- sentinel->initGlyphFromCombinedID(SkGlyph::kImpossibleID); |
- |
- // Initialize all index to zero which points to the sentinel SkGlyph. |
- memset(fGlyphHash, 0x00, sizeof(fGlyphHash)); |
- |
fMemoryUsed = sizeof(*this); |
- fGlyphArray.setReserve(kMinGlyphCount); |
- |
fAuxProcList = NULL; |
- |
-#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
- fHashHitCount = fHashMissCount = 0; |
-#endif |
} |
SkGlyphCache::~SkGlyphCache() { |
-#if 0 |
- { |
- size_t ptrMem = fGlyphArray.count() * sizeof(SkGlyph*); |
- size_t glyphAlloc = fGlyphAlloc.totalCapacity(); |
- size_t glyphHashUsed = 0; |
- size_t uniHashUsed = 0; |
- for (int i = 0; i < kHashCount; ++i) { |
- glyphHashUsed += fGlyphHash[i] ? sizeof(fGlyphHash[0]) : 0; |
- uniHashUsed += fCharToGlyphHash[i].fID != 0xFFFFFFFF ? sizeof(fCharToGlyphHash[0]) : 0; |
- } |
- size_t glyphUsed = fGlyphArray.count() * sizeof(SkGlyph); |
- size_t imageUsed = 0; |
- for (int i = 0; i < fGlyphArray.count(); ++i) { |
- const SkGlyph& g = *fGlyphArray[i]; |
- if (g.fImage) { |
- imageUsed += g.fHeight * g.rowBytes(); |
- } |
- } |
- |
- SkDebugf("glyphPtrArray,%zu, Alloc,%zu, imageUsed,%zu, glyphUsed,%zu, glyphHashAlloc,%zu, glyphHashUsed,%zu, unicharHashAlloc,%zu, unicharHashUsed,%zu\n", |
- ptrMem, glyphAlloc, imageUsed, glyphUsed, sizeof(fGlyphHash), glyphHashUsed, sizeof(CharGlyphRec) * kHashCount, uniHashUsed); |
- |
- } |
-#endif |
- SkGlyph* gptr = fGlyphArray.begin(); |
- SkGlyph* stop = fGlyphArray.end(); |
- while (gptr < stop) { |
- SkPath* path = gptr->fPath; |
- if (path) { |
- SkDELETE(path); |
- } |
- gptr += 1; |
- } |
+ fGlyphMap.foreach([](SkGlyph* g) { if (g->fPath != NULL) { SkDELETE(g->fPath); } } ); |
SkDescriptor::Free(fDesc); |
SkDELETE(fScalerContext); |
this->invokeAndRemoveAuxProcs(); |
@@ -132,28 +76,13 @@ SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) { |
// an fID value that will not match any id. |
for (int i = 0; i <kHashCount; ++i) { |
fCharToGlyphHash[i].fID = SkGlyph::kImpossibleID; |
- fCharToGlyphHash[i].fGlyphIndex = 0; |
+ fCharToGlyphHash[i].fCombinedID = 0; |
} |
} |
return &fCharToGlyphHash[ID2HashIndex(id)]; |
} |
-void SkGlyphCache::adjustCaches(int insertion_index) { |
- for (int i = 0; i < kHashCount; ++i) { |
- if (fGlyphHash[i] >= SkToU16(insertion_index)) { |
- fGlyphHash[i] += 1; |
- } |
- } |
- if (fCharToGlyphHash.get() != NULL) { |
- for (int i = 0; i < kHashCount; ++i) { |
- if (fCharToGlyphHash[i].fGlyphIndex >= SkToU16(insertion_index)) { |
- fCharToGlyphHash[i].fGlyphIndex += 1; |
- } |
- } |
- } |
-} |
- |
/////////////////////////////////////////////////////////////////////////////// |
#ifdef SK_DEBUG |
@@ -168,7 +97,7 @@ uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) { |
const CharGlyphRec& rec = *this->getCharGlyphRec(id); |
if (rec.fID == id) { |
- return fGlyphArray[rec.fGlyphIndex].getGlyphID(); |
+ return SkGlyph::ID2Code(rec.fCombinedID); |
} else { |
return fScalerContext->charToGlyphID(charCode); |
} |
@@ -223,37 +152,24 @@ const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi |
SkGlyph* SkGlyphCache::lookupByChar(SkUnichar charCode, MetricsType type, SkFixed x, SkFixed y) { |
uint32_t id = SkGlyph::MakeID(charCode, x, y); |
CharGlyphRec* rec = this->getCharGlyphRec(id); |
- SkGlyph* glyph; |
if (rec->fID != id) { |
- RecordHashCollisionIf(glyph_index != SkGlyph::kImpossibleID); |
// this ID is based on the UniChar |
rec->fID = id; |
// this ID is based on the glyph index |
- id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); |
- rec->fGlyphIndex = this->lookupMetrics(id, type); |
- glyph = &fGlyphArray[rec->fGlyphIndex]; |
+ int32_t combinedID = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode), x, y); |
+ rec->fCombinedID = combinedID; |
+ return this->lookupByCombinedID(combinedID, type); |
} else { |
- RecordHashSuccess(); |
- glyph = &fGlyphArray[rec->fGlyphIndex]; |
- if (type == kFull_MetricsType && glyph->isJustAdvance()) { |
- fScalerContext->getMetrics(glyph); |
- } |
+ return this->lookupByCombinedID(rec->fCombinedID, type); |
} |
- return glyph; |
} |
SkGlyph* SkGlyphCache::lookupByCombinedID(uint32_t id, MetricsType type) { |
- uint32_t hash_index = ID2HashIndex(id); |
- uint16_t glyph_index = fGlyphHash[hash_index]; |
- SkGlyph* glyph = &fGlyphArray[glyph_index]; |
- |
- if (glyph->fID != id) { |
- RecordHashCollisionIf(glyph_index != SkGlyph::kImpossibleID); |
- glyph_index = this->lookupMetrics(id, type); |
- fGlyphHash[hash_index] = glyph_index; |
- glyph = &fGlyphArray[glyph_index]; |
+ SkGlyph* glyph = fGlyphMap.find(id); |
+ |
+ if (NULL == glyph) { |
+ glyph = this->lookupMetrics(id, type); |
} else { |
- RecordHashSuccess(); |
if (type == kFull_MetricsType && glyph->isJustAdvance()) { |
fScalerContext->getMetrics(glyph); |
} |
@@ -261,55 +177,25 @@ SkGlyph* SkGlyphCache::lookupByCombinedID(uint32_t id, MetricsType type) { |
return glyph; |
} |
-uint16_t SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { |
- SkASSERT(id != SkGlyph::kImpossibleID); |
- // Count is always greater than 0 because of the sentinel. |
- // The fGlyphArray cache is in descending order, so that the sentinel with a value of ~0 is |
- // always at index 0. |
- SkGlyph* gptr = fGlyphArray.begin(); |
- int lo = 0; |
- int hi = fGlyphArray.count() - 1; |
- while (lo < hi) { |
- int mid = (hi + lo) >> 1; |
- if (gptr[mid].fID > id) { |
- lo = mid + 1; |
- } else { |
- hi = mid; |
- } |
- } |
- |
- uint16_t glyph_index = hi; |
- SkGlyph* glyph = &gptr[glyph_index]; |
- if (glyph->fID == id) { |
- if (kFull_MetricsType == mtype && glyph->isJustAdvance()) { |
- fScalerContext->getMetrics(glyph); |
- } |
- SkASSERT(glyph->fID != SkGlyph::kImpossibleID); |
- return glyph_index; |
- } |
- |
- // check if we need to bump hi before falling though to the allocator |
- if (glyph->fID > id) { |
- glyph_index += 1; |
- } |
- |
- // Not found, but hi contains the index of the insertion point of the new glyph. |
+SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) { |
fMemoryUsed += sizeof(SkGlyph); |
- this->adjustCaches(glyph_index); |
- |
- glyph = fGlyphArray.insert(glyph_index); |
- glyph->initGlyphFromCombinedID(id); |
+ SkGlyph* glyphPtr; |
+ { |
+ SkGlyph glyph; |
+ glyph.initGlyphFromCombinedID(id); |
+ glyphPtr = fGlyphMap.set(glyph); |
+ } |
if (kJustAdvance_MetricsType == mtype) { |
- fScalerContext->getAdvance(glyph); |
+ fScalerContext->getAdvance(glyphPtr); |
} else { |
SkASSERT(kFull_MetricsType == mtype); |
- fScalerContext->getMetrics(glyph); |
+ fScalerContext->getMetrics(glyphPtr); |
} |
- SkASSERT(glyph->fID != SkGlyph::kImpossibleID); |
- return glyph_index; |
+ SkASSERT(glyphPtr->fID != SkGlyph::kImpossibleID); |
+ return glyphPtr; |
} |
const void* SkGlyphCache::findImage(const SkGlyph& glyph) { |
@@ -359,11 +245,7 @@ void SkGlyphCache::dump() const { |
matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewX], |
matrix[SkMatrix::kMSkewY], matrix[SkMatrix::kMScaleY], |
rec.fLumBits & 0xFF, rec.fDeviceGamma, rec.fPaintGamma, rec.fContrast, |
- fGlyphArray.count()); |
-#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
- const int sum = SkTMax(fHashHitCount + fHashMissCount, 1); // avoid divide-by-zero |
- msg.appendf(" hash:%2d\n", 100 * fHashHitCount / sum); |
-#endif |
+ fGlyphMap.count()); |
SkDebugf("%s\n", msg.c_str()); |
} |
@@ -533,21 +415,9 @@ void SkGlyphCache::Dump() { |
SkDebugf("SkGlyphCache strikes:%d memory:%d\n", |
globals.getCacheCountUsed(), (int)globals.getTotalMemoryUsed()); |
-#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
- int hitCount = 0; |
- int missCount = 0; |
-#endif |
- |
for (cache = globals.internalGetHead(); cache != NULL; cache = cache->fNext) { |
-#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
- hitCount += cache->fHashHitCount; |
- missCount += cache->fHashMissCount; |
-#endif |
cache->dump(); |
} |
-#ifdef SK_GLYPHCACHE_TRACK_HASH_STATS |
- SkDebugf("Hash hit percent:%2d\n", 100 * hitCount / (hitCount + missCount)); |
-#endif |
} |
/////////////////////////////////////////////////////////////////////////////// |