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

Unified Diff: src/core/SkGlyphCache.cpp

Issue 885903002: Make the glyph array entries inline. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Add hash index adjustment Created 5 years, 11 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..219337af4258872b38fda96e043b236a8b6d9be9 100755
--- a/src/core/SkGlyphCache.cpp
+++ b/src/core/SkGlyphCache.cpp
@@ -68,8 +68,8 @@ SkGlyphCache::SkGlyphCache(SkTypeface* typeface, const SkDescriptor* desc, SkSca
fScalerContext->getFontMetrics(&fFontMetrics);
// init to 0 so that all of the pointers will be null
reed1 2015/01/30 13:57:38 comment (0) disagrees with the code (0xFF) I'm gu
herb_g 2015/02/01 05:09:27 Done.
- memset(fGlyphHash, 0, sizeof(fGlyphHash));
-
+ memset(fGlyphHash, 0xFF, sizeof(fGlyphHash));
+
fMemoryUsed = sizeof(*this);
fGlyphArray.setReserve(kMinGlyphCount);
@@ -106,10 +106,10 @@ SkGlyphCache::~SkGlyphCache() {
}
#endif
- SkGlyph** gptr = fGlyphArray.begin();
- SkGlyph** stop = fGlyphArray.end();
+ SkGlyph* gptr = fGlyphArray.begin();
+ SkGlyph* stop = fGlyphArray.end();
while (gptr < stop) {
- SkPath* path = (*gptr)->fPath;
+ SkPath* path = gptr->fPath;
if (path) {
SkDELETE(path);
}
@@ -120,6 +120,7 @@ SkGlyphCache::~SkGlyphCache() {
this->invokeAndRemoveAuxProcs();
}
+
SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) {
if (NULL == fCharToGlyphHash.get()) {
fCharToGlyphHash.reset(kHashCount);
@@ -131,6 +132,26 @@ SkGlyphCache::CharGlyphRec* SkGlyphCache::getCharGlyphRec(uint32_t id) {
return &fCharToGlyphHash[ID2HashIndex(id)];
}
+void SkGlyphCache::adjustCaches(int16_t insertion_index) {
+ for (int i = 0; i < kHashCount; ++i) {
+ // Beware: the following code uses the wrap around behavior of the
+ // unsigned unint16_t to change the kInvalidGlyph value to zero allowing
+ // a single comparison for if the index needs to be incremented.
+ // This trick is also used below.
+ if (fGlyphHash[i] + 1 >= insertion_index + 1) {
+ fGlyphHash[i] += 1;
+ }
+ }
+ if (fCharToGlyphHash.get() != NULL) {
+ for (int i = 0; i < kHashCount; ++i) {
+ // See the warning about about the following code.
+ if (fCharToGlyphHash[i].fGlyphIndex + 1 >= insertion_index + 1) {
+ fCharToGlyphHash[i].fGlyphIndex += 1;
+ }
+ }
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
@@ -145,7 +166,7 @@ uint16_t SkGlyphCache::unicharToGlyph(SkUnichar charCode) {
const CharGlyphRec& rec = *this->getCharGlyphRec(id);
if (rec.fID == id) {
- return rec.fGlyph->getGlyphID();
+ return fGlyphArray[rec.fGlyphIndex].getGlyphID();
} else {
return fScalerContext->charToGlyphID(charCode);
}
@@ -163,159 +184,125 @@ unsigned SkGlyphCache::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 *maintainCharCache(charCode, kJustAdvance_MetricsType);
}
const SkGlyph& SkGlyphCache::getGlyphIDAdvance(uint16_t glyphID) {
VALIDATE();
uint32_t id = SkGlyph::MakeID(glyphID);
- unsigned index = ID2HashIndex(id);
- SkGlyph* glyph = fGlyphHash[index];
+ return *maintainGlyphCache(id, kJustAdvance_MetricsType);
- 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 *maintainCharCache(charCode, kFull_MetricsType);
}
const SkGlyph& SkGlyphCache::getUnicharMetrics(SkUnichar charCode,
SkFixed x, SkFixed y) {
VALIDATE();
+ return *maintainCharCache(charCode, kFull_MetricsType, x, y);
+}
+
+const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID) {
+ VALIDATE();
+ uint32_t id = SkGlyph::MakeID(glyphID);
+ return *this->maintainGlyphCache(id, kFull_MetricsType);
+}
+
+const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFixed y) {
+ VALIDATE();
+ uint32_t id = SkGlyph::MakeID(glyphID, x, y);
+ return *this->maintainGlyphCache(id, kFull_MetricsType);
+}
+
+SkGlyph* SkGlyphCache::maintainCharCache(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(rec->fGlyph != NULL);
+ RecordHashCollisionIf(rec->fGlyph != kInvalidGlyph);
// 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);
+ rec->fGlyphIndex = this->lookupMetrics(id, kFull_MetricsType);
+ glyph = &fGlyphArray[rec->fGlyphIndex];
} else {
RecordHashSuccess();
- if (rec->fGlyph->isJustAdvance()) {
- fScalerContext->getMetrics(rec->fGlyph);
- }
- }
- SkASSERT(rec->fGlyph->isFullMetrics());
- return *rec->fGlyph;
-}
-
-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()) {
+ glyph = &fGlyphArray[rec->fGlyphIndex];
+ if (type == kFull_MetricsType && glyph->isJustAdvance()) {
fScalerContext->getMetrics(glyph);
}
}
SkASSERT(glyph->isFullMetrics());
- return *glyph;
+ 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) {
+SkGlyph* SkGlyphCache::maintainGlyphCache(uint32_t id, MetricsType type) {
+ uint32_t hash_index = ID2HashIndex(id);
+ uint16_t glyph_index = fGlyphHash[hash_index];
+ SkGlyph* glyph;
+
+ if (kInvalidGlyph == glyph_index
+ || (glyph = &fGlyphArray[glyph_index])->fID != id) {
RecordHashCollisionIf(glyph != NULL);
- glyph = this->lookupMetrics(id, kFull_MetricsType);
- fGlyphHash[index] = glyph;
+ glyph_index = this->lookupMetrics(id, type);
+ fGlyphHash[hash_index] = glyph_index;
+ glyph = &fGlyphArray[glyph_index];
} else {
RecordHashSuccess();
- if (glyph->isJustAdvance()) {
- fScalerContext->getMetrics(glyph);
+ if (type == kFull_MetricsType && glyph->isJustAdvance()) {
+ fScalerContext->getMetrics(glyph);
}
+ SkASSERT(glyph->isFullMetrics());
}
- SkASSERT(glyph->isFullMetrics());
- return *glyph;
+ 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;
-
+uint16_t SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
+ uint16_t glyph_index = 0;
+ int count = fGlyphArray.count();
+ int hi = 0;
+
+ if (count > 0) {
+ SkGlyph* gptr = fGlyphArray.begin();
+ int lo = 0;
+
hi = count - 1;
while (lo < hi) {
int mid = (hi + lo) >> 1;
- if (gptr[mid]->fID < id) {
+ if (gptr[mid].fID < id) {
lo = mid + 1;
} else {
hi = mid;
}
}
- glyph = gptr[hi];
+ glyph_index = hi;
+ SkGlyph* glyph = &gptr[hi];
if (glyph->fID == id) {
if (kFull_MetricsType == mtype && glyph->isJustAdvance()) {
fScalerContext->getMetrics(glyph);
}
- return glyph;
+ return glyph_index;
}
-
+
// check if we need to bump hi before falling though to the allocator
if (glyph->fID < id) {
- hi += 1;
+ glyph_index += 1;
}
}
-
+
// not found, but hi tells us where to inser the new glyph
fMemoryUsed += sizeof(SkGlyph);
+
+ this->adjustCaches(glyph_index);
- glyph = (SkGlyph*)fGlyphAlloc.alloc(sizeof(SkGlyph),
- SkChunkAlloc::kThrow_AllocFailType);
+ SkGlyph* glyph = fGlyphArray.insert(glyph_index);
glyph->init(id);
- *fGlyphArray.insert(hi) = glyph;
if (kJustAdvance_MetricsType == mtype) {
fScalerContext->getAdvance(glyph);
@@ -324,7 +311,7 @@ SkGlyph* SkGlyphCache::lookupMetrics(uint32_t id, MetricsType mtype) {
fScalerContext->getMetrics(glyph);
}
- return glyph;
+ return glyph_index;
}
const void* SkGlyphCache::findImage(const SkGlyph& glyph) {
« 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