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

Unified Diff: src/core/SkGlyphCache.cpp

Issue 912983002: Use SkTHashMap in SkGlyphCache. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: rebase Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkGlyphCache.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkGlyphCache.cpp
diff --git a/src/core/SkGlyphCache.cpp b/src/core/SkGlyphCache.cpp
index 57c54bfc1ec3f7f35d3c499ba14c26abe99bcdcf..31f2485da2052e186a8346130952de6f569b7b21 100755
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -40,24 +40,13 @@ 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)
#define kMinAllocAmount ((sizeof(SkGlyph) + kMinGlyphImageSize) * kMinGlyphCount)
SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkScalerContext* ctx)
- : fScalerContext(ctx), fGlyphAlloc(kMinAllocAmount) {
+ : fScalerContext(ctx), fAlloc(kMinAllocAmount) {
SkASSERT(typeface);
SkASSERT(desc);
SkASSERT(ctx);
@@ -67,70 +56,20 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
fDesc = desc->copy();
fScalerContext->getFontMetrics(&fFontMetrics);
- // init to 0 so that all of the pointers will be null
- memset(fGlyphHash, 0, 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();
- }
- }
+static void delete_path(uint32_t, SkGlyph* glyph) { SkDELETE(glyph->fPath); }
- 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;
- }
+SkGlyphCache::~SkGlyphCache() {
+ fGlyphs.foreach(delete_path);
SkDescriptor::Free(fDesc);
SkDELETE(fScalerContext);
this->invokeAndRemoveAuxProcs();
}
-SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) {
- if (NULL == fCharToGlyphHash.get()) {
- fCharToGlyphHash.reset(kHashCount);
- // init with 0xFF so that the charCode field will be -1, which is invalid
- memset(fCharToGlyphHash.get(), 0xFF,
- sizeof(CharGlyphRec) * kHashCount);
- }
-
- return &fCharToGlyphHash[ID2HashIndex(id)];
-}
-
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
@@ -141,14 +80,12 @@ SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) {
uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) {
VALIDATE();
- uint32_t id = SkGlyph::MakeID(charCode);
- const CharGlyphRec& rec = *this->getCharGlyphRec(id);
-
- if (rec.fID == id) {
- return rec.fGlyph->getGlyphID();
- } else {
- return fScalerContext->charToGlyphID(charCode);
+ if (const uint16_t* glyphID = fCharToGlyphID.find(charCode)) {
+ return *glyphID;
}
+ uint16_t glyphID = fScalerContext->charToGlyphID(charCode);
+ fCharToGlyphID.set(charCode, glyphID);
+ return glyphID;
}
SkUnichar SkGlyphCache::glyphToUnichar(uint16_t glyphID) {
@@ -159,179 +96,66 @@ unsigned SkGlyphCache::getGlyphCount() {
return fScalerContext->getGlyphCount();
}
-///////////////////////////////////////////////////////////////////////////////
-
const SkGlyph& SkGlyphCache::getUnicharAdvance(SkUnichar charCode) {
- VALIDATE();
- uint32_t id = SkGlyph::MakeID(charCode);
- CharGlyphRec* rec = this->getCharGlyphRec(id);
-
- if (rec->fID != id) {
- // this ID is based on the UniChar
- rec->fID = id;
- // this ID is based on the glyph index
- id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode));
- rec->fGlyph = this->lookupMetrics(id, kJustAdvance_MetricsType);
- }
- return *rec->fGlyph;
+ return this->getGlyphIDAdvance(this->unicharToGlyph(charCode));
}
-
-const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) {
- VALIDATE();
- uint32_t id = SkGlyph::MakeID(glyphID);
- unsigned index = ID2HashIndex(id);
- SkGlyph* glyph = fGlyphHash[index];
-
- if (NULL == glyph || glyph->fID != id) {
- glyph = this->lookupMetrics(glyphID, kJustAdvance_MetricsType);
- fGlyphHash[index] = glyph;
- }
- return *glyph;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode) {
- VALIDATE();
- uint32_t id = SkGlyph::MakeID(charCode);
- CharGlyphRec* rec = this->getCharGlyphRec(id);
-
- if (rec->fID != id) {
- RecordHashCollisionIf(rec->fGlyph != NULL);
- // this ID is based on the UniChar
- rec->fID = id;
- // this ID is based on the glyph index
- id = SkGlyph::MakeID(fScalerContext->charToGlyphID(charCode));
- rec->fGlyph = this->lookupMetrics(id, kFull_MetricsType);
- } else {
- RecordHashSuccess();
- if (rec->fGlyph->isJustAdvance()) {
- fScalerContext->getMetrics(rec->fGlyph);
- }
- }
- SkASSERT(rec->fGlyph->isFullMetrics());
- return *rec->fGlyph;
+ return this->getGlyphIDMetrics(this->unicharToGlyph(charCode));
+}
+const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode, SkFixed x, SkFixed y) {
+ return this->getGlyphIDMetrics(this->unicharToGlyph(charCode), x, y);
}
-const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode,
- SkFixed x, SkFixed y) {
+const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) {
VALIDATE();
- uint32_t id = SkGlyph::MakeID(charCode, x, y);
- CharGlyphRec* rec = this->getCharGlyphRec(id);
-
- if (rec->fID != id) {
- RecordHashCollisionIf(rec->fGlyph != NULL);
- // 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->fGlyph = this->lookupMetrics(id, kFull_MetricsType);
- } else {
- RecordHashSuccess();
- if (rec->fGlyph->isJustAdvance()) {
- fScalerContext->getMetrics(rec->fGlyph);
- }
- }
- SkASSERT(rec->fGlyph->isFullMetrics());
- return *rec->fGlyph;
+ const SkGlyph* glyph =
+ this->lookupMetrics(SkGlyph::MakeID(glyphID), kJustAdvance_MetricsType);
+ SkASSERT(glyph);
+ return *glyph;
}
const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) {
VALIDATE();
- uint32_t id = SkGlyph::MakeID(glyphID);
- unsigned index = ID2HashIndex(id);
- SkGlyph* glyph = fGlyphHash[index];
-
- if (NULL == glyph || glyph->fID != id) {
- RecordHashCollisionIf(glyph != NULL);
- glyph = this->lookupMetrics(glyphID, kFull_MetricsType);
- fGlyphHash[index] = glyph;
- } else {
- RecordHashSuccess();
- if (glyph->isJustAdvance()) {
- fScalerContext->getMetrics(glyph);
- }
- }
+ const SkGlyph* glyph =
+ this->lookupMetrics(SkGlyph::MakeID(glyphID), kFull_MetricsType);
+ SkASSERT(glyph);
SkASSERT(glyph->isFullMetrics());
return *glyph;
}
const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFixed y) {
VALIDATE();
- uint32_t id = SkGlyph::MakeID(glyphID, x, y);
- unsigned index = ID2HashIndex(id);
- SkGlyph* glyph = fGlyphHash[index];
-
- if (NULL == glyph || glyph->fID != id) {
- RecordHashCollisionIf(glyph != NULL);
- glyph = this->lookupMetrics(id, kFull_MetricsType);
- fGlyphHash[index] = glyph;
- } else {
- RecordHashSuccess();
- if (glyph->isJustAdvance()) {
- fScalerContext->getMetrics(glyph);
- }
- }
+ const SkGlyph* glyph =
+ this->lookupMetrics(SkGlyph::MakeID(glyphID, x, y), kFull_MetricsType);
+ SkASSERT(glyph);
SkASSERT(glyph->isFullMetrics());
return *glyph;
}
SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
- SkGlyph* glyph;
-
- int hi = 0;
- int count = fGlyphArray.count();
-
- if (count) {
- SkGlyph** gptr = fGlyphArray.begin();
- int lo = 0;
-
- hi = count - 1;
- while (lo < hi) {
- int mid = (hi + lo) >> 1;
- if (gptr[mid]->fID < id) {
- lo = mid + 1;
- } else {
- hi = mid;
- }
- }
- glyph = gptr[hi];
- if (glyph->fID == id) {
- if (kFull_MetricsType == mtype && glyph->isJustAdvance()) {
- fScalerContext->getMetrics(glyph);
- }
- return glyph;
- }
-
- // check if we need to bump hi before falling though to the allocator
- if (glyph->fID < id) {
- hi += 1;
+ if (SkGlyph* glyph = fGlyphs.find(id)) {
+ if (kFull_MetricsType == mtype && glyph->isJustAdvance()) {
+ fScalerContext->getMetrics(glyph);
}
+ return glyph;
}
- // not found, but hi tells us where to inser the new glyph
- fMemoryUsed += sizeof(SkGlyph);
-
- glyph = (SkGlyph*)fGlyphAlloc.alloc(sizeof(SkGlyph),
- SkChunkAlloc::kThrow_AllocFailType);
- glyph->init(id);
- *fGlyphArray.insert(hi) = glyph;
-
+ SkGlyph glyph;
+ glyph.init(id);
if (kJustAdvance_MetricsType == mtype) {
- fScalerContext->getAdvance(glyph);
+ fScalerContext->getAdvance(&glyph);
} else {
SkASSERT(kFull_MetricsType == mtype);
- fScalerContext->getMetrics(glyph);
+ fScalerContext->getMetrics(&glyph);
}
-
- return glyph;
+ return fGlyphs.set(id, glyph);
}
const void* SkGlyphCache::findImage(const SkGlyph& glyph) {
if (glyph.fWidth > 0 && glyph.fWidth < kMaxGlyphWidth) {
if (NULL == glyph.fImage) {
size_t size = glyph.computeImageSize();
- const_cast<SkGlyph&>(glyph).fImage = fGlyphAlloc.alloc(size,
+ const_cast<SkGlyph&>(glyph).fImage = fAlloc.alloc(size,
SkChunkAlloc::kReturnNil_AllocFailType);
// check that alloc() actually succeeded
if (glyph.fImage) {
@@ -374,11 +198,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
+ fGlyphs.count());
SkDebugf("%s\n", msg.c_str());
}
@@ -548,21 +368,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
}
///////////////////////////////////////////////////////////////////////////////
@@ -674,20 +482,6 @@ void SkGlyphCache_Globals::internalDetachCache(SkGlyphCache* cache) {
#ifdef SK_DEBUG
void SkGlyphCache::validate() const {
-#ifdef SK_DEBUG_GLYPH_CACHE
- int count = fGlyphArray.count();
- for (int i = 0; i < count; i++) {
- const SkGlyph* glyph = fGlyphArray[i];
- SkASSERT(glyph);
- SkASSERT(fGlyphAlloc.contains(glyph));
- if (glyph->fImage) {
- SkASSERT(fGlyphAlloc.contains(glyph->fImage));
- }
- if (glyph->fDistanceField) {
- SkASSERT(fGlyphAlloc.contains(glyph->fDistanceField));
- }
- }
-#endif
}
void SkGlyphCache_Globals::validate() const {
« no previous file with comments | « src/core/SkGlyphCache.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698