@@ -109,11 +109,11 @@ CacheBlock* CacheBlock::removeBlock(CacheBlock* head, CacheBlock *blockToRemove)
109109}
110110
111111// /////////////////////////////////////////////////////////////////////////////
112- // CacheTextureLine
112+ // CacheTexture
113113// /////////////////////////////////////////////////////////////////////////////
114114
115- bool CacheTextureLine ::fitBitmap (const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
116- if (glyph.fHeight + TEXTURE_BORDER_SIZE > mMaxHeight ) {
115+ bool CacheTexture ::fitBitmap (const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
116+ if (glyph.fHeight + TEXTURE_BORDER_SIZE > mHeight ) {
117117 return false ;
118118 }
119119
@@ -138,18 +138,18 @@ bool CacheTextureLine::fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uin
138138 roundedUpW = glyphW;
139139 }
140140 *retOriginX = cacheBlock->mX ;
141- *retOriginY = mCurrentRow + cacheBlock->mY ;
141+ *retOriginY = cacheBlock->mY ;
142142 // If this is the remainder space, create a new cache block for this column. Otherwise,
143143 // adjust the info about this column.
144144 if (cacheBlock->mY == TEXTURE_BORDER_SIZE) {
145145 uint16_t oldX = cacheBlock->mX ;
146146 // Adjust remainder space dimensions
147147 cacheBlock->mWidth -= roundedUpW;
148148 cacheBlock->mX += roundedUpW;
149- if (mMaxHeight - glyphH >= glyphH) {
149+ if (mHeight - glyphH >= glyphH) {
150150 // There's enough height left over to create a new CacheBlock
151151 CacheBlock *newBlock = new CacheBlock (oldX, glyphH, roundedUpW,
152- mMaxHeight - glyphH);
152+ mHeight - glyphH);
153153#if DEBUG_FONT_RENDERER
154154 ALOGD (" fitBitmap: Created new block: this, x, y, w, h = %p, %d, %d, %d, %d" ,
155155 newBlock, newBlock->mX , newBlock->mY ,
@@ -213,10 +213,10 @@ Font::~Font() {
213213 }
214214}
215215
216- void Font::invalidateTextureCache (CacheTextureLine *cacheLine ) {
216+ void Font::invalidateTextureCache (CacheTexture *cacheTexture ) {
217217 for (uint32_t i = 0 ; i < mCachedGlyphs .size (); i++) {
218218 CachedGlyphInfo* cachedGlyph = mCachedGlyphs .valueAt (i);
219- if (cacheLine == NULL || cachedGlyph->mCachedTextureLine == cacheLine ) {
219+ if (cacheTexture == NULL || cachedGlyph->mCacheTexture == cacheTexture ) {
220220 cachedGlyph->mIsValid = false ;
221221 }
222222 }
@@ -260,7 +260,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
260260 mState ->appendMeshQuad (nPenX, nPenY, u1, v2,
261261 nPenX + width, nPenY, u2, v2,
262262 nPenX + width, nPenY - height, u2, v1,
263- nPenX, nPenY - height, u1, v1, glyph->mCachedTextureLine -> mCacheTexture );
263+ nPenX, nPenY - height, u1, v1, glyph->mCacheTexture );
264264}
265265
266266void Font::drawCachedGlyphBitmap (CachedGlyphInfo* glyph, int x, int y,
@@ -271,7 +271,7 @@ void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y,
271271 uint32_t endX = glyph->mStartX + glyph->mBitmapWidth ;
272272 uint32_t endY = glyph->mStartY + glyph->mBitmapHeight ;
273273
274- CacheTexture *cacheTexture = glyph->mCachedTextureLine -> mCacheTexture ;
274+ CacheTexture *cacheTexture = glyph->mCacheTexture ;
275275 uint32_t cacheWidth = cacheTexture->mWidth ;
276276 const uint8_t * cacheBuffer = cacheTexture->mTexture ;
277277
@@ -325,7 +325,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float
325325 position->fY + destination[2 ].fY , u2, v1,
326326 position->fX + destination[3 ].fX ,
327327 position->fY + destination[3 ].fY , u1, v1,
328- glyph->mCachedTextureLine -> mCacheTexture );
328+ glyph->mCacheTexture );
329329}
330330
331331CachedGlyphInfo* Font::getCachedGlyph (SkPaint* paint, glyph_t textUnit) {
@@ -556,8 +556,8 @@ void Font::updateGlyphCache(SkPaint* paint, const SkGlyph& skiaGlyph, CachedGlyp
556556 glyph->mBitmapWidth = skiaGlyph.fWidth ;
557557 glyph->mBitmapHeight = skiaGlyph.fHeight ;
558558
559- uint32_t cacheWidth = glyph->mCachedTextureLine -> mCacheTexture ->mWidth ;
560- uint32_t cacheHeight = glyph->mCachedTextureLine -> mCacheTexture ->mHeight ;
559+ uint32_t cacheWidth = glyph->mCacheTexture ->mWidth ;
560+ uint32_t cacheHeight = glyph->mCacheTexture ->mHeight ;
561561
562562 glyph->mBitmapMinU = startX / (float ) cacheWidth;
563563 glyph->mBitmapMinV = startY / (float ) cacheHeight;
@@ -620,10 +620,6 @@ FontRenderer::FontRenderer() {
620620 mTextMeshPtr = NULL ;
621621 mCurrentCacheTexture = NULL ;
622622 mLastCacheTexture = NULL ;
623- mCacheTextureSmall = NULL ;
624- mCacheTexture128 = NULL ;
625- mCacheTexture256 = NULL ;
626- mCacheTexture512 = NULL ;
627623
628624 mLinearFiltering = false ;
629625
@@ -659,21 +655,17 @@ FontRenderer::FontRenderer() {
659655}
660656
661657FontRenderer::~FontRenderer () {
662- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
663- delete mCacheLines [i];
658+ for (uint32_t i = 0 ; i < mCacheTextures .size (); i++) {
659+ delete mCacheTextures [i];
664660 }
665- mCacheLines .clear ();
661+ mCacheTextures .clear ();
666662
667663 if (mInitialized ) {
668664 // Unbinding the buffer shouldn't be necessary but it crashes with some drivers
669665 Caches::getInstance ().unbindIndicesBuffer ();
670666 glDeleteBuffers (1 , &mIndexBufferID );
671667
672668 delete[] mTextMeshPtr ;
673- delete mCacheTextureSmall ;
674- delete mCacheTexture128 ;
675- delete mCacheTexture256 ;
676- delete mCacheTexture512 ;
677669 }
678670
679671 Vector<Font*> fontsToDereference = mActiveFonts ;
@@ -692,29 +684,19 @@ void FontRenderer::flushAllAndInvalidate() {
692684 mActiveFonts [i]->invalidateTextureCache ();
693685 }
694686
695- uint16_t totalGlyphs = 0 ;
696- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
697- totalGlyphs += mCacheLines [i]->mNumGlyphs ;
698- mCacheLines [i]->init ();
687+ for (uint32_t i = 0 ; i < mCacheTextures .size (); i++) {
688+ mCacheTextures [i]->init ();
699689 }
700690
701- #if DEBUG_FONT_RENDERER
702- // Erase caches, just as a debugging facility
703- if (mCacheTextureSmall && mCacheTextureSmall ->mTexture ) {
704- memset (mCacheTextureSmall ->mTexture , 0 ,
705- mCacheTextureSmall ->mWidth * mCacheTextureSmall ->mHeight );
706- }
707- if (mCacheTexture128 && mCacheTexture128 ->mTexture ) {
708- memset (mCacheTexture128 ->mTexture , 0 ,
709- mCacheTexture128 ->mWidth * mCacheTexture128 ->mHeight );
710- }
711- if (mCacheTexture256 && mCacheTexture256 ->mTexture ) {
712- memset (mCacheTexture256 ->mTexture , 0 ,
713- mCacheTexture256 ->mWidth * mCacheTexture256 ->mHeight );
714- }
715- if (mCacheTexture512 && mCacheTexture512 ->mTexture ) {
716- memset (mCacheTexture512 ->mTexture , 0 ,
717- mCacheTexture512 ->mWidth * mCacheTexture512 ->mHeight );
691+ #if DEBUG_FONT_RENDERER
692+ uint16_t totalGlyphs = 0 ;
693+ for (uint32_t i = 0 ; i < mCacheTextures .size (); i++) {
694+ totalGlyphs += mCacheTextures [i]->mNumGlyphs ;
695+ // Erase caches, just as a debugging facility
696+ if (mCacheTextures [i]->mTexture ) {
697+ memset (mCacheTextures [i]->mTexture , 0 ,
698+ mCacheTextures [i]->mWidth * mCacheTextures [i]->mHeight );
699+ }
718700 }
719701 ALOGD (" Flushing caches: glyphs cached = %d" , totalGlyphs);
720702#endif
@@ -730,38 +712,17 @@ void FontRenderer::deallocateTextureMemory(CacheTexture *cacheTexture) {
730712}
731713
732714void FontRenderer::flushLargeCaches () {
733- if ((!mCacheTexture128 || !mCacheTexture128 ->mTexture ) &&
734- (!mCacheTexture256 || !mCacheTexture256 ->mTexture ) &&
735- (!mCacheTexture512 || !mCacheTexture512 ->mTexture )) {
736- // Typical case; no large glyph caches allocated
737- return ;
738- }
739-
740- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
741- CacheTextureLine* cacheLine = mCacheLines [i];
742- if ((cacheLine->mCacheTexture == mCacheTexture128 ||
743- cacheLine->mCacheTexture == mCacheTexture256 ||
744- cacheLine->mCacheTexture == mCacheTexture512 ) &&
745- cacheLine->mCacheTexture ->mTexture != NULL ) {
746- #if DEBUG_FONT_RENDERER
747- if (cacheLine->mCacheTexture == mCacheTexture128 ) {
748- ALOGD (" flushing cacheTexture128" );
749- } else if (cacheLine->mCacheTexture == mCacheTexture256 ) {
750- ALOGD (" flushing cacheTexture256" );
751- } else {
752- ALOGD (" flushing cacheTexture512" );
753- }
754- #endif
755- cacheLine->init ();
756- for (uint32_t i = 0 ; i < mActiveFonts .size (); i++) {
757- mActiveFonts [i]->invalidateTextureCache (cacheLine);
715+ // Start from 1; don't deallocate smallest/default texture
716+ for (uint32_t i = 1 ; i < mCacheTextures .size (); i++) {
717+ CacheTexture* cacheTexture = mCacheTextures [i];
718+ if (cacheTexture->mTexture != NULL ) {
719+ cacheTexture->init ();
720+ for (uint32_t j = 0 ; j < mActiveFonts .size (); j++) {
721+ mActiveFonts [j]->invalidateTextureCache (cacheTexture);
758722 }
723+ deallocateTextureMemory (cacheTexture);
759724 }
760725 }
761-
762- deallocateTextureMemory (mCacheTexture128 );
763- deallocateTextureMemory (mCacheTexture256 );
764- deallocateTextureMemory (mCacheTexture512 );
765726}
766727
767728void FontRenderer::allocateTextureMemory (CacheTexture* cacheTexture) {
@@ -789,12 +750,24 @@ void FontRenderer::allocateTextureMemory(CacheTexture* cacheTexture) {
789750 glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
790751}
791752
753+ CacheTexture* FontRenderer::cacheBitmapInTexture (const SkGlyph& glyph,
754+ uint32_t * startX, uint32_t * startY) {
755+ for (uint32_t i = 0 ; i < mCacheTextures .size (); i++) {
756+ if (mCacheTextures [i]->fitBitmap (glyph, startX, startY)) {
757+ return mCacheTextures [i];
758+ }
759+ }
760+ // Could not fit glyph into current cache textures
761+ return NULL ;
762+ }
763+
792764void FontRenderer::cacheBitmap (const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
793765 uint32_t * retOriginX, uint32_t * retOriginY) {
794766 checkInit ();
795767 cachedGlyph->mIsValid = false ;
796768 // If the glyph is too tall, don't cache it
797- if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mCacheLines [mCacheLines .size () - 1 ]->mMaxHeight ) {
769+ if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 >
770+ mCacheTextures [mCacheTextures .size () - 1 ]->mHeight ) {
798771 ALOGE (" Font size too large to fit in cache. width, height = %i, %i" ,
799772 (int ) glyph.fWidth , (int ) glyph.fHeight );
800773 return ;
@@ -804,46 +777,31 @@ void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyp
804777 uint32_t startX = 0 ;
805778 uint32_t startY = 0 ;
806779
807- bool bitmapFit = false ;
808- CacheTextureLine *cacheLine;
809- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
810- bitmapFit = mCacheLines [i]->fitBitmap (glyph, &startX, &startY);
811- if (bitmapFit) {
812- cacheLine = mCacheLines [i];
813- break ;
814- }
815- }
780+ CacheTexture* cacheTexture = cacheBitmapInTexture (glyph, &startX, &startY);
816781
817782 // If the new glyph didn't fit, flush the state so far and invalidate everything
818- if (!bitmapFit ) {
783+ if (!cacheTexture ) {
819784 flushAllAndInvalidate ();
820785
821786 // Try to fit it again
822- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
823- bitmapFit = mCacheLines [i]->fitBitmap (glyph, &startX, &startY);
824- if (bitmapFit) {
825- cacheLine = mCacheLines [i];
826- break ;
827- }
828- }
787+ cacheTexture = cacheBitmapInTexture (glyph, &startX, &startY);
829788
830789 // if we still don't fit, something is wrong and we shouldn't draw
831- if (!bitmapFit ) {
790+ if (!cacheTexture ) {
832791 return ;
833792 }
834793 }
835794
836- cachedGlyph->mCachedTextureLine = cacheLine ;
795+ cachedGlyph->mCacheTexture = cacheTexture ;
837796
838797 *retOriginX = startX;
839798 *retOriginY = startY;
840799
841800 uint32_t endX = startX + glyph.fWidth ;
842801 uint32_t endY = startY + glyph.fHeight ;
843802
844- uint32_t cacheWidth = cacheLine-> mMaxWidth ;
803+ uint32_t cacheWidth = cacheTexture-> mWidth ;
845804
846- CacheTexture* cacheTexture = cacheLine->mCacheTexture ;
847805 if (!cacheTexture->mTexture ) {
848806 // Large-glyph texture memory is allocated only as needed
849807 allocateTextureMemory (cacheTexture);
@@ -896,17 +854,10 @@ CacheTexture* FontRenderer::createCacheTexture(int width, int height, bool alloc
896854}
897855
898856void FontRenderer::initTextTexture () {
899- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
900- delete mCacheLines [i];
901- }
902- mCacheLines .clear ();
903-
904- if (mCacheTextureSmall ) {
905- delete mCacheTextureSmall ;
906- delete mCacheTexture128 ;
907- delete mCacheTexture256 ;
908- delete mCacheTexture512 ;
857+ for (uint32_t i = 0 ; i < mCacheTextures .size (); i++) {
858+ delete mCacheTextures [i];
909859 }
860+ mCacheTextures .clear ();
910861
911862 // Next, use other, separate caches for large glyphs.
912863 uint16_t maxWidth = 0 ;
@@ -918,35 +869,12 @@ void FontRenderer::initTextTexture() {
918869 maxWidth = MAX_TEXT_CACHE_WIDTH;
919870 }
920871
921- mCacheTextureSmall = createCacheTexture (mSmallCacheWidth , mSmallCacheHeight , true );
922- mCacheTexture128 = createCacheTexture (maxWidth, 256 , false );
923- mCacheTexture256 = createCacheTexture (maxWidth, 256 , false );
924- mCacheTexture512 = createCacheTexture (maxWidth, 512 , false );
925- mCurrentCacheTexture = mCacheTextureSmall ;
926-
927872 mUploadTexture = false ;
928- // Split up our default cache texture into lines of certain widths
929- int nextLine = 0 ;
930- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , 18 , nextLine, mCacheTextureSmall ));
931- nextLine += mCacheLines .top ()->mMaxHeight ;
932- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , 26 , nextLine, mCacheTextureSmall ));
933- nextLine += mCacheLines .top ()->mMaxHeight ;
934- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , 26 , nextLine, mCacheTextureSmall ));
935- nextLine += mCacheLines .top ()->mMaxHeight ;
936- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , 34 , nextLine, mCacheTextureSmall ));
937- nextLine += mCacheLines .top ()->mMaxHeight ;
938- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , 34 , nextLine, mCacheTextureSmall ));
939- nextLine += mCacheLines .top ()->mMaxHeight ;
940- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , 42 , nextLine, mCacheTextureSmall ));
941- nextLine += mCacheLines .top ()->mMaxHeight ;
942- mCacheLines .push (new CacheTextureLine (mSmallCacheWidth , mSmallCacheHeight - nextLine,
943- nextLine, mCacheTextureSmall ));
944-
945- // The first cache is split into 2 lines of height 128, the rest have just one cache line.
946- mCacheLines .push (new CacheTextureLine (maxWidth, 128 , 0 , mCacheTexture128 ));
947- mCacheLines .push (new CacheTextureLine (maxWidth, 128 , 128 , mCacheTexture128 ));
948- mCacheLines .push (new CacheTextureLine (maxWidth, 256 , 0 , mCacheTexture256 ));
949- mCacheLines .push (new CacheTextureLine (maxWidth, 512 , 0 , mCacheTexture512 ));
873+ mCacheTextures .push (createCacheTexture (mSmallCacheWidth , mSmallCacheHeight , true ));
874+ mCacheTextures .push (createCacheTexture (maxWidth, 256 , false ));
875+ mCacheTextures .push (createCacheTexture (maxWidth, 256 , false ));
876+ mCacheTextures .push (createCacheTexture (maxWidth, 512 , false ));
877+ mCurrentCacheTexture = mCacheTextures [0 ];
950878}
951879
952880// Avoid having to reallocate memory and render quad by quad
@@ -1001,30 +929,28 @@ void FontRenderer::checkTextureUpdate() {
1001929
1002930 Caches& caches = Caches::getInstance ();
1003931 GLuint lastTextureId = 0 ;
1004- // Iterate over all the cache lines and see which ones need to be updated
1005- for (uint32_t i = 0 ; i < mCacheLines .size (); i++) {
1006- CacheTextureLine* cl = mCacheLines [i];
1007- if (cl->mDirty && cl->mCacheTexture ->mTexture != NULL ) {
1008- CacheTexture* cacheTexture = cl->mCacheTexture ;
932+ // Iterate over all the cache textures and see which ones need to be updated
933+ for (uint32_t i = 0 ; i < mCacheTextures .size (); i++) {
934+ CacheTexture* cacheTexture = mCacheTextures [i];
935+ if (cacheTexture->mDirty && cacheTexture->mTexture != NULL ) {
1009936 uint32_t xOffset = 0 ;
1010- uint32_t yOffset = cl->mCurrentRow ;
1011- uint32_t width = cl->mMaxWidth ;
1012- uint32_t height = cl->mMaxHeight ;
1013- void * textureData = cacheTexture->mTexture + (yOffset * width);
937+ uint32_t width = cacheTexture->mWidth ;
938+ uint32_t height = cacheTexture->mHeight ;
939+ void * textureData = cacheTexture->mTexture ;
1014940
1015941 if (cacheTexture->mTextureId != lastTextureId) {
1016942 caches.activeTexture (0 );
1017943 glBindTexture (GL_TEXTURE_2D, cacheTexture->mTextureId );
1018944 lastTextureId = cacheTexture->mTextureId ;
1019945 }
1020946#if DEBUG_FONT_RENDERER
1021- ALOGD (" glTextSubimage for cacheLine %d: xOff, yOff, width height = %d, %d, %d, %d " , i ,
1022- xOffset, yOffset , width, height);
947+ ALOGD (" glTextSubimage for cacheTexture %d: xOff, width height = %d, %d, %d" ,
948+ i, xOffset , width, height);
1023949#endif
1024- glTexSubImage2D (GL_TEXTURE_2D, 0 , xOffset, yOffset , width, height,
950+ glTexSubImage2D (GL_TEXTURE_2D, 0 , xOffset, 0 , width, height,
1025951 GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
1026952
1027- cl ->mDirty = false ;
953+ cacheTexture ->mDirty = false ;
1028954 }
1029955 }
1030956
0 commit comments