Skip to content

Commit b92d8f7

Browse files
committed
Optimize glyph cache texture uploads
Only upload the changed area of the glyph cache, not the entire bitmap. Note that we can't do the full-on optimization here of copying a sub-rect of the bitmap because of GL ES 2 limitations, but we can at least copy the horizontal stripe containing the dirty rect, which can still be a big savings over uploading the entire bitmap. Issue #7158326 Bad framerates on MR1 (Mako, Manta, Prime) Change-Id: Iab38d53202650f757ead4658cf4287bdad2b3cb9
1 parent 7b770b0 commit b92d8f7

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

libs/hwui/FontRenderer.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -331,23 +331,26 @@ void FontRenderer::checkTextureUpdate() {
331331
for (uint32_t i = 0; i < mCacheTextures.size(); i++) {
332332
CacheTexture* cacheTexture = mCacheTextures[i];
333333
if (cacheTexture->isDirty() && cacheTexture->getTexture()) {
334-
uint32_t xOffset = 0;
334+
// Can't copy inner rect; glTexSubimage expects pointer to deal with entire buffer
335+
// of data. So expand the dirty rect to the encompassing horizontal stripe.
336+
const Rect* dirtyRect = cacheTexture->getDirtyRect();
337+
uint32_t x = 0;
338+
uint32_t y = dirtyRect->top;
335339
uint32_t width = cacheTexture->getWidth();
336-
uint32_t height = cacheTexture->getHeight();
337-
void* textureData = cacheTexture->getTexture();
340+
uint32_t height = dirtyRect->getHeight();
341+
void* textureData = cacheTexture->getTexture() + y * width;
338342

339343
if (cacheTexture->getTextureId() != lastTextureId) {
340344
lastTextureId = cacheTexture->getTextureId();
341345
caches.activeTexture(0);
342346
glBindTexture(GL_TEXTURE_2D, lastTextureId);
343347
}
344348
#if DEBUG_FONT_RENDERER
345-
ALOGD("glTextSubimage for cacheTexture %d: xOff, width height = %d, %d, %d",
346-
i, xOffset, width, height);
349+
ALOGD("glTexSubimage for cacheTexture %d: x, y, width height = %d, %d, %d, %d",
350+
i, x, y, width, height);
347351
#endif
348-
glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, 0, width, height,
352+
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
349353
GL_ALPHA, GL_UNSIGNED_BYTE, textureData);
350-
351354
cacheTexture->setDirty(false);
352355
}
353356
}

libs/hwui/font/CacheTexture.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_
171171
}
172172

173173
mDirty = true;
174+
const Rect r(*retOriginX - TEXTURE_BORDER_SIZE, *retOriginY - TEXTURE_BORDER_SIZE,
175+
*retOriginX + glyphW, *retOriginY + glyphH);
176+
mDirtyRect.unionWith(r);
174177
mNumGlyphs++;
175178

176179
#if DEBUG_FONT_RENDERER

libs/hwui/font/CacheTexture.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <utils/Log.h>
2525

2626
#include "FontUtil.h"
27+
#include "Rect.h"
2728

2829
namespace android {
2930
namespace uirenderer {
@@ -149,6 +150,10 @@ class CacheTexture {
149150
return mHeight;
150151
}
151152

153+
inline const Rect* getDirtyRect() const {
154+
return &mDirtyRect;
155+
}
156+
152157
inline uint8_t* getTexture() const {
153158
return mTexture;
154159
}
@@ -163,6 +168,9 @@ class CacheTexture {
163168

164169
inline void setDirty(bool dirty) {
165170
mDirty = dirty;
171+
if (!dirty) {
172+
mDirtyRect.setEmpty();
173+
}
166174
}
167175

168176
inline bool getLinearFiltering() const {
@@ -196,6 +204,7 @@ class CacheTexture {
196204
bool mDirty;
197205
uint16_t mNumGlyphs;
198206
CacheBlock* mCacheBlocks;
207+
Rect mDirtyRect;
199208
};
200209

201210
}; // namespace uirenderer

0 commit comments

Comments
 (0)