diff options
| -rw-r--r-- | libs/hwui/FontRenderer.cpp | 66 | ||||
| -rw-r--r-- | libs/hwui/FontRenderer.h | 11 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 2 |
3 files changed, 65 insertions, 14 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 14ad7d7227f9..5595ab0220d6 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -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, diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index bacd3aadba4f..2f7a8bac305a 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -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; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index d30d7180028e..2e44e122ea39 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -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); |