When font cache still has empty space,
precache some commonly used characters to reduce studder. Change-Id: I1f66f57482c4a025672dfd1d8ecaf2b9736cd9a0
This commit is contained in:
@@ -80,6 +80,21 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y) {
|
||||
nPenX, nPenY - height, 0, u1, v1);
|
||||
}
|
||||
|
||||
Font::CachedGlyphInfo* Font::getCachedUTFChar(SkPaint* paint, int32_t utfChar) {
|
||||
CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(utfChar);
|
||||
if (cachedGlyph == NULL) {
|
||||
cachedGlyph = cacheGlyph(paint, utfChar);
|
||||
}
|
||||
|
||||
// Is the glyph still in texture cache?
|
||||
if (!cachedGlyph->mIsValid) {
|
||||
const SkGlyph& skiaGlyph = paint->getUnicharMetrics(utfChar);
|
||||
updateGlyphCache(paint, skiaGlyph, cachedGlyph);
|
||||
}
|
||||
|
||||
return cachedGlyph;
|
||||
}
|
||||
|
||||
void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t len,
|
||||
int numGlyphs, int x, int y) {
|
||||
if (numGlyphs == 0 || text == NULL || len == 0) {
|
||||
@@ -102,16 +117,7 @@ void Font::renderUTF(SkPaint* paint, const char* text, uint32_t start, uint32_t
|
||||
break;
|
||||
}
|
||||
|
||||
CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(utfChar);
|
||||
if (cachedGlyph == NULL) {
|
||||
cachedGlyph = cacheGlyph(paint, utfChar);
|
||||
}
|
||||
|
||||
// Is the glyph still in texture cache?
|
||||
if (!cachedGlyph->mIsValid) {
|
||||
const SkGlyph& skiaGlyph = paint->getUnicharMetrics(utfChar);
|
||||
updateGlyphCache(paint, skiaGlyph, cachedGlyph);
|
||||
}
|
||||
CachedGlyphInfo* cachedGlyph = getCachedUTFChar(paint, utfChar);
|
||||
|
||||
// If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
|
||||
if (cachedGlyph->mIsValid) {
|
||||
@@ -340,6 +346,8 @@ void FontRenderer::initTextTexture() {
|
||||
nextLine += mCacheLines.top()->mMaxHeight;
|
||||
mCacheLines.push(new CacheTextureLine(mCacheWidth, 24, nextLine, 0));
|
||||
nextLine += mCacheLines.top()->mMaxHeight;
|
||||
mCacheLines.push(new CacheTextureLine(mCacheWidth, 24, nextLine, 0));
|
||||
nextLine += mCacheLines.top()->mMaxHeight;
|
||||
mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0));
|
||||
nextLine += mCacheLines.top()->mMaxHeight;
|
||||
mCacheLines.push(new CacheTextureLine(mCacheWidth, 32, nextLine, 0));
|
||||
@@ -392,6 +400,12 @@ void FontRenderer::checkInit() {
|
||||
initTextTexture();
|
||||
initVertexArrayBuffers();
|
||||
|
||||
// We store a string with letters in a rough frequency of occurrence
|
||||
mLatinPrecache = String16("eisarntolcdugpmhbyfvkwzxjq ");
|
||||
mLatinPrecache += String16("EISARNTOLCDUGPMHBYFVKWZXJQ");
|
||||
mLatinPrecache += String16(",.?!()-+@;:`'");
|
||||
mLatinPrecache += String16("0123456789");
|
||||
|
||||
mInitialized = true;
|
||||
}
|
||||
|
||||
@@ -484,8 +498,38 @@ void FontRenderer::appendMeshQuad(float x1, float y1, float z1, float u1, float
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderer::setFont(uint32_t fontId, float fontSize) {
|
||||
uint32_t FontRenderer::getRemainingCacheCapacity() {
|
||||
uint32_t remainingCapacity = 0;
|
||||
float totalPixels = 0;
|
||||
for(uint32_t i = 0; i < mCacheLines.size(); i ++) {
|
||||
remainingCapacity += (mCacheLines[i]->mMaxWidth - mCacheLines[i]->mCurrentCol);
|
||||
totalPixels += mCacheLines[i]->mMaxWidth;
|
||||
}
|
||||
remainingCapacity = (remainingCapacity * 100) / totalPixels;
|
||||
return remainingCapacity;
|
||||
}
|
||||
|
||||
void FontRenderer::precacheLatin(SkPaint* paint) {
|
||||
// Remaining capacity is measured in %
|
||||
uint32_t remainingCapacity = getRemainingCacheCapacity();
|
||||
uint32_t precacheIdx = 0;
|
||||
while(remainingCapacity > 25 && precacheIdx < mLatinPrecache.size()) {
|
||||
mCurrentFont->getCachedUTFChar(paint, (int32_t)mLatinPrecache[precacheIdx]);
|
||||
remainingCapacity = getRemainingCacheCapacity();
|
||||
precacheIdx ++;
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderer::setFont(SkPaint* paint, uint32_t fontId, float fontSize) {
|
||||
uint32_t currentNumFonts = mActiveFonts.size();
|
||||
mCurrentFont = Font::create(this, fontId, fontSize);
|
||||
|
||||
const float maxPrecacheFontSize = 40.0f;
|
||||
bool isNewFont = currentNumFonts != mActiveFonts.size();
|
||||
|
||||
if(isNewFont && fontSize <= maxPrecacheFontSize ){
|
||||
precacheLatin(paint);
|
||||
}
|
||||
}
|
||||
|
||||
void FontRenderer::renderText(SkPaint* paint, const Rect* clip, const char *text,
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define ANDROID_UI_FONT_RENDERER_H
|
||||
|
||||
#include <utils/String8.h>
|
||||
#include <utils/String16.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
|
||||
@@ -82,10 +83,12 @@ protected:
|
||||
|
||||
void invalidateTextureCache();
|
||||
|
||||
CachedGlyphInfo *cacheGlyph(SkPaint* paint, int32_t glyph);
|
||||
CachedGlyphInfo* cacheGlyph(SkPaint* paint, int32_t glyph);
|
||||
void updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyphInfo *glyph);
|
||||
void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
|
||||
|
||||
CachedGlyphInfo* getCachedUTFChar(SkPaint* paint, int32_t utfChar);
|
||||
|
||||
FontRenderer* mState;
|
||||
uint32_t mFontId;
|
||||
float mFontSize;
|
||||
@@ -99,7 +102,7 @@ public:
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
void setFont(uint32_t fontId, float fontSize);
|
||||
void setFont(SkPaint* paint, uint32_t fontId, float fontSize);
|
||||
void renderText(SkPaint* paint, const Rect* clip, const char *text, uint32_t startIndex,
|
||||
uint32_t len, int numGlyphs, int x, int y);
|
||||
|
||||
@@ -160,6 +163,9 @@ protected:
|
||||
|
||||
void checkInit();
|
||||
|
||||
String16 mLatinPrecache;
|
||||
void precacheLatin(SkPaint* paint);
|
||||
|
||||
void issueDrawCommand();
|
||||
void appendMeshQuad(float x1, float y1, float z1, float u1, float v1, float x2, float y2,
|
||||
float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3,
|
||||
@@ -169,6 +175,7 @@ protected:
|
||||
uint32_t mCacheHeight;
|
||||
|
||||
Vector<CacheTextureLine*> mCacheLines;
|
||||
uint32_t getRemainingCacheCapacity();
|
||||
|
||||
Font* mCurrentFont;
|
||||
Vector<Font*> mActiveFonts;
|
||||
|
||||
@@ -569,7 +569,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
|
||||
// TODO: Implement scale properly
|
||||
const Rect& clip = mSnapshot->getLocalClip();
|
||||
|
||||
mFontRenderer.setFont(SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
|
||||
mFontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()), paint->getTextSize());
|
||||
mFontRenderer.renderText(paint, &clip, text, 0, bytesCount, count, x, y);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
Reference in New Issue
Block a user