Merge "Avoid thrashing the glyph cache during the precache phase" into jb-mr1-dev
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 27e198c..6b08e7f 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -328,19 +328,19 @@
glyph->mCacheTexture);
}
-CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit) {
+CachedGlyphInfo* Font::getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching) {
CachedGlyphInfo* cachedGlyph = NULL;
ssize_t index = mCachedGlyphs.indexOfKey(textUnit);
if (index >= 0) {
cachedGlyph = mCachedGlyphs.valueAt(index);
} else {
- cachedGlyph = cacheGlyph(paint, textUnit);
+ cachedGlyph = cacheGlyph(paint, textUnit, precaching);
}
// Is the glyph still in texture cache?
if (!cachedGlyph->mIsValid) {
const SkGlyph& skiaGlyph = GET_METRICS(paint, textUnit);
- updateGlyphCache(paint, skiaGlyph, cachedGlyph);
+ updateGlyphCache(paint, skiaGlyph, cachedGlyph, precaching);
}
return cachedGlyph;
@@ -438,7 +438,7 @@
break;
}
- CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
+ CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph, true);
glyphsCount++;
}
@@ -529,7 +529,8 @@
}
}
-void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph) {
+void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
+ bool precaching) {
glyph->mAdvanceX = skiaGlyph.fAdvanceX;
glyph->mAdvanceY = skiaGlyph.fAdvanceY;
glyph->mBitmapLeft = skiaGlyph.fLeft;
@@ -542,7 +543,7 @@
// Get the bitmap for the glyph
paint->findImage(skiaGlyph);
- mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY);
+ mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
if (!glyph->mIsValid) {
return;
@@ -567,7 +568,7 @@
mState->mUploadTexture = true;
}
-CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph) {
+CachedGlyphInfo* Font::cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching) {
CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
mCachedGlyphs.add(glyph, newGlyph);
@@ -575,7 +576,7 @@
newGlyph->mGlyphIndex = skiaGlyph.fID;
newGlyph->mIsValid = false;
- updateGlyphCache(paint, skiaGlyph, newGlyph);
+ updateGlyphCache(paint, skiaGlyph, newGlyph, precaching);
return newGlyph;
}
@@ -762,7 +763,7 @@
}
void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
- uint32_t* retOriginX, uint32_t* retOriginY) {
+ uint32_t* retOriginX, uint32_t* retOriginY, bool precaching) {
checkInit();
cachedGlyph->mIsValid = false;
// If the glyph is too tall, don't cache it
@@ -779,15 +780,16 @@
CacheTexture* cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
- // If the new glyph didn't fit, flush the state so far and invalidate everything
if (!cacheTexture) {
- flushAllAndInvalidate();
+ if (!precaching) {
+ // If the new glyph didn't fit and we are not just trying to precache it,
+ // clear out the cache and try again
+ flushAllAndInvalidate();
+ cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
+ }
- // Try to fit it again
- cacheTexture = cacheBitmapInTexture(glyph, &startX, &startY);
-
- // if we still don't fit, something is wrong and we shouldn't draw
if (!cacheTexture) {
+ // either the glyph didn't fit or we're precaching and will cache it when we draw
return;
}
}
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index febae17..8d0d21d 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -243,8 +243,9 @@
void invalidateTextureCache(CacheTexture *cacheTexture = NULL);
- CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph);
- void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph);
+ CachedGlyphInfo* cacheGlyph(SkPaint* paint, glyph_t glyph, bool precaching);
+ void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo* glyph,
+ bool precaching);
void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
@@ -258,7 +259,7 @@
void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
SkPathMeasure& measure, SkPoint* position, SkVector* tangent);
- CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit);
+ CachedGlyphInfo* getCachedGlyph(SkPaint* paint, glyph_t textUnit, bool precaching = false);
static glyph_t nextGlyph(const uint16_t** srcPtr) {
const uint16_t* src = *srcPtr;
@@ -364,7 +365,7 @@
void initTextTexture();
CacheTexture* createCacheTexture(int width, int height, bool allocate);
void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
- uint32_t *retOriginX, uint32_t *retOriginY);
+ uint32_t *retOriginX, uint32_t *retOriginY, bool precaching);
CacheTexture* cacheBitmapInTexture(const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
void flushAllAndInvalidate();