Updating parts of font cache as needed instead of the entire map.
Change-Id: If9a37e10197255122acdb5b10a0c356edd942d67
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 24dee55..14ad7d7 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -199,11 +199,12 @@
mInitialized = false;
mMaxNumberOfQuads = 1024;
mCurrentQuadIndex = 0;
+ mTextureId = 0;
mIndexBufferID = 0;
mCacheWidth = DEFAULT_TEXT_CACHE_WIDTH;
- mCacheHeight = DEFAULT_TEXT_CACHE_WIDTH;
+ mCacheHeight = DEFAULT_TEXT_CACHE_HEIGHT;
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
@@ -227,7 +228,12 @@
}
mCacheLines.clear();
+ delete mTextMeshPtr;
+
delete mTextTexture;
+ if(mTextureId) {
+ glDeleteTextures(1, &mTextureId);
+ }
Vector<Font*> fontsToDereference = mActiveFonts;
for (uint32_t i = 0; i < fontsToDereference.size(); i++) {
@@ -318,6 +324,9 @@
glGenTextures(1, &mTextureId);
glBindTexture(GL_TEXTURE_2D, mTextureId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ // Initialize texture dimentions
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -370,9 +379,8 @@
uint32_t coordSize = 3;
uint32_t uvSize = 2;
uint32_t vertsPerQuad = 4;
- uint32_t vertexBufferSizeBytes = mMaxNumberOfQuads * vertsPerQuad * coordSize *
- uvSize * sizeof(float);
- mTextMeshPtr = (float*) malloc(vertexBufferSizeBytes);
+ uint32_t vertexBufferSize = mMaxNumberOfQuads * vertsPerQuad * coordSize * uvSize;
+ mTextMeshPtr = new float[vertexBufferSize];
}
// We don't want to allocate anything unless we actually draw text
@@ -387,14 +395,37 @@
mInitialized = true;
}
-void FontRenderer::issueDrawCommand() {
- if (mUploadTexture) {
- glBindTexture(GL_TEXTURE_2D, mTextureId);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, mCacheWidth, mCacheHeight, 0, GL_ALPHA,
- GL_UNSIGNED_BYTE, mTextTexture);
- mUploadTexture = false;
+void FontRenderer::checkTextureUpdate() {
+ if (!mUploadTexture) {
+ return;
}
+ glBindTexture(GL_TEXTURE_2D, mTextureId);
+
+ // Iterate over all the cache lines and see which ones need to be updated
+ for (uint32_t i = 0; i < mCacheLines.size(); i++) {
+ CacheTextureLine* cl = mCacheLines[i];
+ if(cl->mDirty) {
+ uint32_t xOffset = 0;
+ uint32_t yOffset = cl->mCurrentRow;
+ uint32_t width = mCacheWidth;
+ uint32_t height = cl->mMaxHeight;
+ void* textureData = mTextTexture + yOffset*width;
+
+ glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height,
+ GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
+
+ cl->mDirty = false;
+ }
+ }
+
+ mUploadTexture = false;
+}
+
+void FontRenderer::issueDrawCommand() {
+
+ checkTextureUpdate();
+
float* vtx = mTextMeshPtr;
float* tex = vtx + 3;
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index c1cd7fb..bacd3aa 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -116,13 +116,15 @@
uint16_t mMaxWidth;
uint32_t mCurrentRow;
uint32_t mCurrentCol;
+ bool mDirty;
CacheTextureLine(uint16_t maxWidth, uint16_t maxHeight, uint32_t currentRow,
uint32_t currentCol):
mMaxHeight(maxHeight),
mMaxWidth(maxWidth),
mCurrentRow(currentRow),
- mCurrentCol(currentCol) {
+ mCurrentCol(currentCol),
+ mDirty(false) {
}
bool fitBitmap(const SkGlyph& glyph, uint32_t *retOriginX, uint32_t *retOriginY) {
@@ -134,6 +136,7 @@
*retOriginX = mCurrentCol;
*retOriginY = mCurrentRow;
mCurrentCol += glyph.fWidth;
+ mDirty = true;
return true;
}
@@ -173,6 +176,7 @@
// Texture to cache glyph bitmaps
unsigned char* mTextTexture;
GLuint mTextureId;
+ void checkTextureUpdate();
bool mUploadTexture;
// Pointer to vertex data to speed up frame to frame work