summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorSangkyu Lee <geteuid@gmail.com>2012-11-16 00:03:17 +0900
committerSangkyu Lee <geteuid@gmail.com>2012-11-28 09:28:50 +0900
commit7bb3cfe1cca4016ce95d3ef059761f4bb2d668bb (patch)
treeb9440572c9d1e7fb3d82c26996444c3fe2ba7fbe /libs
parentc88047bf86fd83e5b0204d26b35776cad97ed877 (diff)
downloadframeworks_base-7bb3cfe1cca4016ce95d3ef059761f4bb2d668bb.zip
frameworks_base-7bb3cfe1cca4016ce95d3ef059761f4bb2d668bb.tar.gz
frameworks_base-7bb3cfe1cca4016ce95d3ef059761f4bb2d668bb.tar.bz2
Another optimization of glyph cache uploads
Previously, cache textures were updated whenever mCurrentCacheTexuture was changed. Since updating cache textures needs glTexSubImage2D call, frequent changing of mCurrentCacheTexture (which can easily happen when an app uses lots of unique glyphs even with precaching) caused many glTexSubImage2D calls and bad framerates. This patch optimized isssueDrawCommand function. Consequently, changing mCurrentCacheTexture doesn't cause glTexSubImage2D call any more and it will improve font rendering performance. Change-Id: Id19d959fa0e69eeb2a39f83a57e311d7394586b2 Signed-off-by: Sangkyu Lee <geteuid@gmail.com>
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/FontRenderer.cpp49
-rw-r--r--libs/hwui/FontRenderer.h7
2 files changed, 37 insertions, 19 deletions
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index 4e97c88..47784a4 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -45,10 +45,10 @@ FontRenderer::FontRenderer() {
mInitialized = false;
mMaxNumberOfQuads = 1024;
mCurrentQuadIndex = 0;
+ mLastQuadIndex = 0;
mTextMesh = NULL;
mCurrentCacheTexture = NULL;
- mLastCacheTexture = NULL;
mLinearFiltering = false;
@@ -116,7 +116,6 @@ FontRenderer::~FontRenderer() {
void FontRenderer::flushAllAndInvalidate() {
if (mCurrentQuadIndex != 0) {
issueDrawCommand();
- mCurrentQuadIndex = 0;
}
for (uint32_t i = 0; i < mActiveFonts.size(); i++) {
@@ -320,8 +319,17 @@ void FontRenderer::checkInit() {
mInitialized = true;
}
+void FontRenderer::updateDrawParams() {
+ if (mCurrentQuadIndex != mLastQuadIndex) {
+ mDrawOffsets.add((uint16_t*)(mLastQuadIndex * sizeof(uint16_t) * 6));
+ mDrawCounts.add(mCurrentQuadIndex - mLastQuadIndex);
+ mDrawCacheTextures.add(mCurrentCacheTexture);
+ mLastQuadIndex = mCurrentQuadIndex;
+ }
+}
+
void FontRenderer::checkTextureUpdate() {
- if (!mUploadTexture && mLastCacheTexture == mCurrentCacheTexture) {
+ if (!mUploadTexture) {
return;
}
@@ -355,16 +363,11 @@ void FontRenderer::checkTextureUpdate() {
}
}
- caches.activeTexture(0);
- glBindTexture(GL_TEXTURE_2D, mCurrentCacheTexture->getTextureId());
-
- mCurrentCacheTexture->setLinearFiltering(mLinearFiltering, false);
- mLastCacheTexture = mCurrentCacheTexture;
-
mUploadTexture = false;
}
void FontRenderer::issueDrawCommand() {
+ updateDrawParams();
checkTextureUpdate();
Caches& caches = Caches::getInstance();
@@ -378,20 +381,33 @@ void FontRenderer::issueDrawCommand() {
caches.bindTexCoordsVertexPointer(force, buffer + offset);
}
- glDrawElements(GL_TRIANGLES, mCurrentQuadIndex * 6, GL_UNSIGNED_SHORT, NULL);
+ for (uint32_t i = 0; i < mDrawOffsets.size(); i++) {
+ uint16_t* offset = mDrawOffsets[i];
+ uint32_t count = mDrawCounts[i];
+ CacheTexture* texture = mDrawCacheTextures[i];
+
+ caches.activeTexture(0);
+ glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
+
+ texture->setLinearFiltering(mLinearFiltering, false);
+
+ glDrawElements(GL_TRIANGLES, count * 6, GL_UNSIGNED_SHORT, offset);
+ }
mDrawn = true;
+
+ mCurrentQuadIndex = 0;
+ mLastQuadIndex = 0;
+ mDrawOffsets.clear();
+ mDrawCounts.clear();
+ mDrawCacheTextures.clear();
}
void FontRenderer::appendMeshQuadNoClip(float x1, float y1, float u1, float v1,
float x2, float y2, float u2, float v2, float x3, float y3, float u3, float v3,
float x4, float y4, float u4, float v4, CacheTexture* texture) {
if (texture != mCurrentCacheTexture) {
- if (mCurrentQuadIndex != 0) {
- // First, draw everything stored already which uses the previous texture
- issueDrawCommand();
- mCurrentQuadIndex = 0;
- }
+ updateDrawParams();
// Now use the new texture id
mCurrentCacheTexture = texture;
}
@@ -443,7 +459,6 @@ void FontRenderer::appendMeshQuad(float x1, float y1, float u1, float v1,
if (mCurrentQuadIndex == mMaxNumberOfQuads) {
issueDrawCommand();
- mCurrentQuadIndex = 0;
}
}
@@ -462,7 +477,6 @@ void FontRenderer::appendRotatedMeshQuad(float x1, float y1, float u1, float v1,
if (mCurrentQuadIndex == mMaxNumberOfQuads) {
issueDrawCommand();
- mCurrentQuadIndex = 0;
}
}
@@ -544,7 +558,6 @@ void FontRenderer::finishRender() {
if (mCurrentQuadIndex != 0) {
issueDrawCommand();
- mCurrentQuadIndex = 0;
}
}
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
index 405db09..09a3c25 100644
--- a/libs/hwui/FontRenderer.h
+++ b/libs/hwui/FontRenderer.h
@@ -138,6 +138,7 @@ private:
void removeFont(const Font* font);
+ void updateDrawParams();
void checkTextureUpdate();
void setTextureDirty() {
@@ -155,13 +156,13 @@ private:
Vector<Font*> mActiveFonts;
CacheTexture* mCurrentCacheTexture;
- CacheTexture* mLastCacheTexture;
bool mUploadTexture;
// Pointer to vertex data to speed up frame to frame work
float* mTextMesh;
uint32_t mCurrentQuadIndex;
+ uint32_t mLastQuadIndex;
uint32_t mMaxNumberOfQuads;
uint32_t mIndexBufferID;
@@ -174,6 +175,10 @@ private:
bool mLinearFiltering;
+ Vector<uint16_t*> mDrawOffsets;
+ Vector<uint32_t> mDrawCounts;
+ Vector<CacheTexture*> mDrawCacheTextures;
+
/** We should consider multi-threading this code or using Renderscript **/
static void computeGaussianWeights(float* weights, int32_t radius);
static void horizontalBlur(float* weights, int32_t radius, const uint8_t *source, uint8_t *dest,