diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/FontRenderer.cpp | 65 | ||||
| -rw-r--r-- | libs/hwui/FontRenderer.h | 23 |
2 files changed, 54 insertions, 34 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index 9e7fbb5..a0bf8e3 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -540,9 +540,11 @@ void FontRenderer::flushAllAndInvalidate() { issueDrawCommand(); mCurrentQuadIndex = 0; } + for (uint32_t i = 0; i < mActiveFonts.size(); i++) { mActiveFonts[i]->invalidateTextureCache(); } + for (uint32_t i = 0; i < mCacheLines.size(); i++) { mCacheLines[i]->mCurrentCol = 0; } @@ -551,8 +553,9 @@ void FontRenderer::flushAllAndInvalidate() { void FontRenderer::deallocateTextureMemory(CacheTexture *cacheTexture) { if (cacheTexture && cacheTexture->mTexture) { glDeleteTextures(1, &cacheTexture->mTextureId); - delete cacheTexture->mTexture; + delete[] cacheTexture->mTexture; cacheTexture->mTexture = NULL; + cacheTexture->mTextureId = 0; } } @@ -582,11 +585,19 @@ void FontRenderer::flushLargeCaches() { deallocateTextureMemory(mCacheTexture512); } -void FontRenderer::allocateTextureMemory(CacheTexture *cacheTexture) { +void FontRenderer::allocateTextureMemory(CacheTexture* cacheTexture) { int width = cacheTexture->mWidth; int height = cacheTexture->mHeight; + cacheTexture->mTexture = new uint8_t[width * height]; +#if DEBUG_FONT_RENDERER memset(cacheTexture->mTexture, 0, width * height * sizeof(uint8_t)); +#endif + + if (!cacheTexture->mTextureId) { + glGenTextures(1, &cacheTexture->mTextureId); + } + glBindTexture(GL_TEXTURE_2D, cacheTexture->mTextureId); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Initialize texture dimensions @@ -654,11 +665,12 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp uint32_t cacheWidth = cacheLine->mMaxWidth; - CacheTexture *cacheTexture = cacheLine->mCacheTexture; - if (cacheTexture->mTexture == NULL) { + CacheTexture* cacheTexture = cacheLine->mCacheTexture; + if (!cacheTexture->mTexture) { // Large-glyph texture memory is allocated only as needed allocateTextureMemory(cacheTexture); } + uint8_t* cacheBuffer = cacheTexture->mTexture; uint8_t* bitmapBuffer = (uint8_t*) glyph.fImage; unsigned int stride = glyph.rowBytes(); @@ -675,34 +687,39 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp } CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool allocate) { - GLuint textureId; - glGenTextures(1, &textureId); uint8_t* textureMemory = NULL; + CacheTexture* cacheTexture = new CacheTexture(textureMemory, width, height); - CacheTexture* cacheTexture = new CacheTexture(textureMemory, textureId, width, height); if (allocate) { allocateTextureMemory(cacheTexture); } + return cacheTexture; } void FontRenderer::initTextTexture() { + for (uint32_t i = 0; i < mCacheLines.size(); i++) { + delete mCacheLines[i]; + } mCacheLines.clear(); + if (mCacheTextureSmall) { + delete mCacheTextureSmall; + delete mCacheTexture128; + delete mCacheTexture256; + delete mCacheTexture512; + } + // Next, use other, separate caches for large glyphs. uint16_t maxWidth = 0; if (Caches::hasInstance()) { maxWidth = Caches::getInstance().maxTextureSize; } + if (maxWidth > MAX_TEXT_CACHE_WIDTH || maxWidth == 0) { maxWidth = MAX_TEXT_CACHE_WIDTH; } - if (mCacheTextureSmall != NULL) { - delete mCacheTextureSmall; - delete mCacheTexture128; - delete mCacheTexture256; - delete mCacheTexture512; - } + mCacheTextureSmall = createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, true); mCacheTexture128 = createCacheTexture(maxWidth, 256, false); mCacheTexture256 = createCacheTexture(maxWidth, 256, false); @@ -776,12 +793,6 @@ 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; } @@ -944,11 +955,19 @@ uint32_t FontRenderer::getRemainingCacheCapacity() { 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->getCachedGlyph(paint, (int32_t) mLatinPrecache[precacheIdx]); + uint32_t precacheIndex = 0; + + // We store a string with letters in a rough frequency of occurrence + String16 l("eisarntolcdugpmhbyfvkwzxjq EISARNTOLCDUGPMHBYFVKWZXJQ,.?!()-+@;:'0123456789"); + + size_t size = l.size(); + uint16_t latin[size]; + paint->utfToGlyphs(l.string(), SkPaint::kUTF16_TextEncoding, size * sizeof(char16_t), latin); + + while (remainingCapacity > 25 && precacheIndex < size) { + mCurrentFont->getCachedGlyph(paint, TO_GLYPH(latin[precacheIndex])); remainingCapacity = getRemainingCacheCapacity(); - precacheIdx ++; + precacheIndex++; } } diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h index 4fc5862..2ab680e 100644 --- a/libs/hwui/FontRenderer.h +++ b/libs/hwui/FontRenderer.h @@ -41,11 +41,13 @@ namespace uirenderer { #if RENDER_TEXT_AS_GLYPHS typedef uint16_t glyph_t; + #define TO_GLYPH(g) g #define GET_METRICS(paint, glyph) paint->getGlyphMetrics(glyph) #define GET_GLYPH(text) nextGlyph((const uint16_t**) &text) #define IS_END_OF_STRING(glyph) false #else typedef SkUnichar glyph_t; + #define TO_GLYPH(g) ((SkUnichar) g) #define GET_METRICS(paint, glyph) paint->getUnicharMetrics(glyph) #define GET_GLYPH(text) SkUTF16_NextUnichar((const uint16_t**) &text) #define IS_END_OF_STRING(glyph) glyph < 0 @@ -59,15 +61,15 @@ class FontRenderer; class CacheTexture { public: - CacheTexture(){} - CacheTexture(uint8_t* texture, GLuint textureId, uint16_t width, uint16_t height) : - mTexture(texture), mTextureId(textureId), mWidth(width), mHeight(height), - mLinearFiltering(false) {} + CacheTexture() { } + CacheTexture(uint8_t* texture, uint16_t width, uint16_t height) : + mTexture(texture), mTextureId(0), mWidth(width), mHeight(height), + mLinearFiltering(false) { } ~CacheTexture() { - if (mTexture != NULL) { + if (mTexture) { delete[] mTexture; } - if (mTextureId != 0) { + if (mTextureId) { glDeleteTextures(1, &mTextureId); } } @@ -88,7 +90,7 @@ public: mCurrentRow(currentRow), mCurrentCol(currentCol), mDirty(false), - mCacheTexture(cacheTexture){ + mCacheTexture(cacheTexture) { } bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY); @@ -98,7 +100,7 @@ public: uint32_t mCurrentRow; uint32_t mCurrentCol; bool mDirty; - CacheTexture *mCacheTexture; + CacheTexture* mCacheTexture; }; struct CachedGlyphInfo { @@ -236,8 +238,6 @@ public: FontRenderer(); ~FontRenderer(); - void init(); - void deinit(); void flushLargeCaches(); void setGammaTable(const uint8_t* gammaTable) { @@ -278,6 +278,7 @@ public: GLuint getTexture(bool linearFiltering = false) { checkInit(); + if (linearFiltering != mCurrentCacheTexture->mLinearFiltering) { mCurrentCacheTexture->mLinearFiltering = linearFiltering; mLinearFiltering = linearFiltering; @@ -287,6 +288,7 @@ public: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); } + return mCurrentCacheTexture->mTextureId; } @@ -326,7 +328,6 @@ protected: void initRender(const Rect* clip, Rect* bounds); void finishRender(); - String16 mLatinPrecache; void precacheLatin(SkPaint* paint); void issueDrawCommand(); |
