Skip to content

Commit 2ccc47b

Browse files
Romain GuyAndroid (Google) Code Review
authored andcommitted
Merge "Memory optimizations for libhwui Bug #5566149" into ics-mr1
2 parents fd900f0 + eca0ca2 commit 2ccc47b

File tree

6 files changed

+127
-27
lines changed

6 files changed

+127
-27
lines changed

libs/hwui/Caches.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,11 @@ void Caches::flush(FlushMode mode) {
170170
patchCache.clear();
171171
dropShadowCache.clear();
172172
gradientCache.clear();
173+
fontRenderer.clear();
173174
// fall through
174175
case kFlushMode_Moderate:
176+
fontRenderer.flush();
177+
textureCache.flush();
175178
pathCache.clear();
176179
roundRectShapeCache.clear();
177180
circleShapeCache.clear();

libs/hwui/GammaFontRenderer.cpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,20 +67,63 @@ GammaFontRenderer::GammaFontRenderer() {
6767
const float whiteGamma = 1.0f / gamma;
6868

6969
for (uint32_t i = 0; i <= 255; i++) {
70-
mDefault[i] = i;
70+
mGammaTable[i] = i;
7171

7272
const float v = i / 255.0f;
7373
const float black = pow(v, blackGamma);
7474
const float white = pow(v, whiteGamma);
7575

76-
mBlackGamma[i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
77-
mWhiteGamma[i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
76+
mGammaTable[256 + i] = uint8_t((float)::floor(black * 255.0f + 0.5f));
77+
mGammaTable[512 + i] = uint8_t((float)::floor(white * 255.0f + 0.5f));
7878
}
7979

80-
// Configure the font renderers
81-
mDefaultRenderer.setGammaTable(&mDefault[0]);
82-
mBlackGammaRenderer.setGammaTable(&mBlackGamma[0]);
83-
mWhiteGammaRenderer.setGammaTable(&mWhiteGamma[0]);
80+
memset(mRenderers, 0, sizeof(FontRenderer*) * kGammaCount);
81+
memset(mRenderersUsageCount, 0, sizeof(uint32_t) * kGammaCount);
82+
}
83+
84+
GammaFontRenderer::~GammaFontRenderer() {
85+
for (int i = 0; i < kGammaCount; i++) {
86+
delete mRenderers[i];
87+
}
88+
}
89+
90+
void GammaFontRenderer::clear() {
91+
for (int i = 0; i < kGammaCount; i++) {
92+
delete mRenderers[i];
93+
mRenderers[i] = NULL;
94+
}
95+
}
96+
97+
void GammaFontRenderer::flush() {
98+
int count = 0;
99+
int min = -1;
100+
uint32_t minCount = UINT_MAX;
101+
102+
for (int i = 0; i < kGammaCount; i++) {
103+
if (mRenderers[i]) {
104+
count++;
105+
if (mRenderersUsageCount[i] < minCount) {
106+
minCount = mRenderersUsageCount[i];
107+
min = i;
108+
}
109+
}
110+
}
111+
112+
if (count <= 1 || min < 0) return;
113+
114+
delete mRenderers[min];
115+
mRenderers[min] = NULL;
116+
}
117+
118+
FontRenderer* GammaFontRenderer::getRenderer(Gamma gamma) {
119+
FontRenderer* renderer = mRenderers[gamma];
120+
if (!renderer) {
121+
renderer = new FontRenderer();
122+
mRenderers[gamma] = renderer;
123+
renderer->setGammaTable(&mGammaTable[gamma * 256]);
124+
}
125+
mRenderersUsageCount[gamma]++;
126+
return renderer;
84127
}
85128

86129
FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
@@ -92,12 +135,12 @@ FontRenderer& GammaFontRenderer::getFontRenderer(const SkPaint* paint) {
92135
const int luminance = (r * 2 + g * 5 + b) >> 3;
93136

94137
if (luminance <= mBlackThreshold) {
95-
return mBlackGammaRenderer;
138+
return *getRenderer(kGammaBlack);
96139
} else if (luminance >= mWhiteThreshold) {
97-
return mWhiteGammaRenderer;
140+
return *getRenderer(kGammaWhite);
98141
}
99142
}
100-
return mDefaultRenderer;
143+
return *getRenderer(kGammaDefault);
101144
}
102145

103146
}; // namespace uirenderer

libs/hwui/GammaFontRenderer.h

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,36 +26,43 @@ namespace uirenderer {
2626

2727
struct GammaFontRenderer {
2828
GammaFontRenderer();
29+
~GammaFontRenderer();
30+
31+
enum Gamma {
32+
kGammaDefault = 0,
33+
kGammaBlack = 1,
34+
kGammaWhite = 2,
35+
kGammaCount = 3
36+
};
37+
38+
void clear();
39+
void flush();
2940

3041
FontRenderer& getFontRenderer(const SkPaint* paint);
3142

3243
uint32_t getFontRendererCount() const {
33-
return 3;
44+
return kGammaCount;
3445
}
3546

3647
uint32_t getFontRendererSize(uint32_t fontRenderer) const {
37-
switch (fontRenderer) {
38-
case 0:
39-
return mDefaultRenderer.getCacheHeight() * mDefaultRenderer.getCacheWidth();
40-
case 1:
41-
return mBlackGammaRenderer.getCacheHeight() * mBlackGammaRenderer.getCacheWidth();
42-
case 2:
43-
return mWhiteGammaRenderer.getCacheHeight() * mWhiteGammaRenderer.getCacheWidth();
44-
}
45-
return 0;
48+
if (fontRenderer >= kGammaCount) return 0;
49+
50+
FontRenderer* renderer = mRenderers[fontRenderer];
51+
if (!renderer) return 0;
52+
53+
return renderer->getCacheHeight() * renderer->getCacheWidth();
4654
}
4755

4856
private:
49-
FontRenderer mDefaultRenderer;
50-
FontRenderer mBlackGammaRenderer;
51-
FontRenderer mWhiteGammaRenderer;
57+
FontRenderer* getRenderer(Gamma gamma);
58+
59+
uint32_t mRenderersUsageCount[kGammaCount];
60+
FontRenderer* mRenderers[kGammaCount];
5261

5362
int mBlackThreshold;
5463
int mWhiteThreshold;
5564

56-
uint8_t mDefault[256];
57-
uint8_t mBlackGamma[256];
58-
uint8_t mWhiteGamma[256];
65+
uint8_t mGammaTable[256 * kGammaCount];
5966
};
6067

6168
}; // namespace uirenderer

libs/hwui/Properties.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ enum DebugLevel {
6161
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
6262
#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
6363

64+
// These properties are defined in percentage (range 0..1)
65+
#define PROPERTY_TEXTURE_CACHE_FLUSH_RATE "ro.hwui.texture_cache_flush_rate"
66+
6467
// These properties are defined in pixels
6568
#define PROPERTY_TEXT_CACHE_WIDTH "ro.hwui.text_cache_width"
6669
#define PROPERTY_TEXT_CACHE_HEIGHT "ro.hwui.text_cache_height"
@@ -82,6 +85,8 @@ enum DebugLevel {
8285
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
8386
#define DEFAULT_FBO_CACHE_SIZE 16
8487

88+
#define DEFAULT_TEXTURE_CACHE_FLUSH_RATE 0.6f
89+
8590
#define DEFAULT_TEXT_GAMMA 1.4f
8691
#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
8792
#define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192

libs/hwui/TextureCache.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ namespace uirenderer {
3434

3535
TextureCache::TextureCache():
3636
mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
37-
mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)) {
37+
mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)),
38+
mFlushRate(DEFAULT_TEXTURE_CACHE_FLUSH_RATE) {
3839
char property[PROPERTY_VALUE_MAX];
3940
if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
4041
INIT_LOGD(" Setting texture cache size to %sMB", property);
@@ -43,6 +44,15 @@ TextureCache::TextureCache():
4344
INIT_LOGD(" Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE);
4445
}
4546

47+
if (property_get(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, property, NULL) > 0) {
48+
float flushRate = atof(property);
49+
INIT_LOGD(" Setting texture cache flush rate to %.2f%%", flushRate * 100.0f);
50+
setFlushRate(flushRate);
51+
} else {
52+
INIT_LOGD(" Using default texture cache flush rate of %.2f%%",
53+
DEFAULT_TEXTURE_CACHE_FLUSH_RATE * 100.0f);
54+
}
55+
4656
init();
4757
}
4858

@@ -84,6 +94,10 @@ void TextureCache::setMaxSize(uint32_t maxSize) {
8494
}
8595
}
8696

97+
void TextureCache::setFlushRate(float flushRate) {
98+
mFlushRate = fmaxf(0.0f, fminf(1.0f, flushRate));
99+
}
100+
87101
///////////////////////////////////////////////////////////////////////////////
88102
// Callbacks
89103
///////////////////////////////////////////////////////////////////////////////
@@ -168,6 +182,21 @@ void TextureCache::clear() {
168182
TEXTURE_LOGD("TextureCache:clear(), mSize = %d", mSize);
169183
}
170184

185+
void TextureCache::flush() {
186+
if (mFlushRate >= 1.0f || mCache.size() == 0) return;
187+
if (mFlushRate <= 0.0f) {
188+
clear();
189+
return;
190+
}
191+
192+
uint32_t targetSize = uint32_t(mSize * mFlushRate);
193+
TEXTURE_LOGD("TextureCache::flush: target size: %d", targetSize);
194+
195+
while (mSize > targetSize) {
196+
mCache.removeOldest();
197+
}
198+
}
199+
171200
void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
172201
SkAutoLockPixels alp(*bitmap);
173202

libs/hwui/TextureCache.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ class TextureCache: public OnEntryRemoved<SkBitmap*, Texture*> {
9898
*/
9999
uint32_t getSize();
100100

101+
/**
102+
* Partially flushes the cache. The amount of memory freed by a flush
103+
* is defined by the flush rate.
104+
*/
105+
void flush();
106+
/**
107+
* Indicates the percentage of the cache to retain when a
108+
* memory trim is requested (see Caches::flush).
109+
*/
110+
void setFlushRate(float flushRate);
111+
101112
private:
102113
/**
103114
* Generates the texture from a bitmap into the specified texture structure.
@@ -119,6 +130,8 @@ class TextureCache: public OnEntryRemoved<SkBitmap*, Texture*> {
119130
uint32_t mMaxSize;
120131
GLint mMaxTextureSize;
121132

133+
float mFlushRate;
134+
122135
bool mDebugEnabled;
123136

124137
Vector<SkBitmap*> mGarbage;

0 commit comments

Comments
 (0)