Skip to content

Commit f942cf1

Browse files
committed
Avoid thrashing the glyph cache during the precache phase
It is unlikely, but possible, to draw so many glyphs in a frame (especially of the glyphs are quite large) that the cache starts flushing itself to fit the later glyphs in. This causes unnecessary thrashing, because when we actually draw the frame, we will again need to flush to fit the earlier glyphs in, and then flush again to fit the later ones in. It is better to avoid thrashing the cache at the precache phase, and wait until we actually draw the glyphs that do not fit to do any eviction of the earlier glyphs. This change simply notes when we are in the preaching phase, and avoids flushing the cache when a glyph does not fit. Issue #7081725 avoid thrashing cache during DisplayList recording Change-Id: I230410ab5b478091b1032fa99dc1752acf868bbe
1 parent 71d7c3c commit f942cf1

File tree

2 files changed

+22
-19
lines changed

2 files changed

+22
-19
lines changed

libs/hwui/FontRenderer.cpp

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -328,19 +328,19 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float
328328
glyph->mCacheTexture);
329329
}
330330

331-
CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit) {
331+
CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching) {
332332
CachedGlyphInfo* cachedGlyph = NULL;
333333
ssize_t index = mCachedGlyphs.indexOfKey(textUnit);
334334
if (index >= 0) {
335335
cachedGlyph = mCachedGlyphs.valueAt(index);
336336
} else {
337-
cachedGlyph = cacheGlyph(paint, textUnit);
337+
cachedGlyph = cacheGlyph(paint, textUnit, precaching);
338338
}
339339

340340
// Is the glyph still in texture cache?
341341
if (!cachedGlyph->mIsValid) {
342342
const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit);
343-
updateGlyphCache(paint, skiaGlyph, cachedGlyph);
343+
updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
344344
}
345345

346346
return cachedGlyph;
@@ -438,7 +438,7 @@ void Font::precache(SkPaint* paint, const char* text, int numGlyphs) {
438438
break;
439439
}
440440

441-
CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
441+
CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph, true);
442442

443443
glyphsCount++;
444444
}
@@ -529,7 +529,8 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len
529529
}
530530
}
531531

532-
void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph) {
532+
void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
533+
bool precaching) {
533534
glyph->mAdvanceX = skiaGlyph.fAdvanceX;
534535
glyph->mAdvanceY = skiaGlyph.fAdvanceY;
535536
glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -542,7 +543,7 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
542543

543544
// Get the bitmap for the glyph
544545
paint->findImage(skiaGlyph);
545-
mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY);
546+
mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
546547

547548
if (!glyph->mIsValid) {
548549
return;
@@ -567,15 +568,15 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
567568
mState->mUploadTexture = true;
568569
}
569570

570-
CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph) {
571+
CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching) {
571572
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
572573
mCachedGlyphs.add(glyph, newGlyph);
573574

574575
const SkGlyph& skiaGlyph = GET_METRICS(paint, glyph);
575576
newGlyph->mGlyphIndex = skiaGlyph.fID;
576577
newGlyph->mIsValid = false;
577578

578-
updateGlyphCache(paint, skiaGlyph, newGlyph);
579+
updateGlyphCache(paint, skiaGlyph, newGlyph, precaching);
579580

580581
return newGlyph;
581582
}
@@ -762,7 +763,7 @@ CacheTexture* FontRenderer::cacheBitmapInTexture(const SkGlyph& glyph,
762763
}
763764

764765
void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
765-
uint32_t* retOriginX, uint32_t* retOriginY) {
766+
uint32_t* retOriginX, uint32_t* retOriginY, bool precaching) {
766767
checkInit();
767768
cachedGlyph->mIsValid = false;
768769
// If the glyph is too tall, don't cache it
@@ -779,15 +780,16 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
779780

780781
CacheTexture* cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
781782

782-
// If the new glyph didn't fit, flush the state so far and invalidate everything
783783
if (!cacheTexture) {
784-
flushAllAndInvalidate();
785-
786-
// Try to fit it again
787-
cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
784+
if (!precaching) {
785+
// If the new glyph didn't fit and we are not just trying to precache it,
786+
// clear out the cache and try again
787+
flushAllAndInvalidate();
788+
cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
789+
}
788790

789-
// if we still don't fit, something is wrong and we shouldn't draw
790791
if (!cacheTexture) {
792+
// either the glyph didn't fit or we're precaching and will cache it when we draw
791793
return;
792794
}
793795
}

libs/hwui/FontRenderer.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,9 @@ class Font {
243243

244244
void invalidateTextureCache(CacheTexture *cacheTexture = NULL);
245245

246-
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph);
247-
void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph);
246+
CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
247+
void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
248+
bool precaching);
248249

249250
void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
250251
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
@@ -258,7 +259,7 @@ class Font {
258259
void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
259260
SkPathMeasure& measure, SkPoint* position, SkVector* tangent);
260261

261-
CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit);
262+
CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching = false);
262263

263264
static glyph_t nextGlyph(const uint16_t** srcPtr) {
264265
const uint16_t* src = *srcPtr;
@@ -364,7 +365,7 @@ class FontRenderer {
364365
void initTextTexture();
365366
CacheTexture* createCacheTexture(int width, int height, bool allocate);
366367
void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
367-
uint32_t *retOriginX, uint32_t *retOriginY);
368+
uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
368369
CacheTexture* cacheBitmapInTexture(const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
369370

370371
void flushAllAndInvalidate();

0 commit comments

Comments
 (0)