1
0
Fork 1

Don't produce ram-expensive Bitmap just for letter

Instead save a very small object with the string in it and draw every
time. Drawing a single letter is not noticibly slower than blitting a
bitmap of the same size. It may even be faster, and certainly saves RAM.

(cherry picked from commit c996da3a0eefc197b8ea887790bdf8d73736b1ed)
This commit is contained in:
Stephen Paul Weber 2024-10-08 23:05:40 -05:00 committed by Arne
parent 3666e846b8
commit 3f84cf9939
2 changed files with 51 additions and 12 deletions

View file

@ -4,7 +4,9 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
@ -545,14 +547,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
}*/
public Drawable get(final String name, String seed, final int size, boolean cachedOnly) {
final String KEY = key(seed == null ? name : name+"\0"+seed, size);
Drawable bitmap = mXmppConnectionService.getDrawableCache().get(KEY);
if (bitmap != null || cachedOnly) {
return bitmap;
}
bitmap = getImpl(name, seed, size);
mXmppConnectionService.getDrawableCache().put(KEY, bitmap);
return bitmap;
return getImpl(name, seed, size);
}
public static Drawable get(final Jid jid, final int size) {
@ -563,8 +558,7 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
final String trimmedName = name == null ? "" : name.trim();
drawTile(canvas, trimmedName, seed, 0, 0, size, size);
return new BitmapDrawable(bitmap);
return new TextDrawable(name, seed, size);
}
private String key(String name, int size) {
@ -693,4 +687,47 @@ public class AvatarService implements OnAdvancedStreamFeaturesLoaded {
@ColorInt int getAvatarBackgroundColor();
String getAvatarName();
}
public static class TextDrawable extends Drawable {
protected final String name;
protected final String seed;
protected final int size;
public TextDrawable(final String name, final String seed, final int size) {
this.name = name;
this.seed = seed;
this.size = size;
}
@Override
public void draw(Canvas canvas) {
final var r = getBounds();
drawTile(canvas, name, seed, r.left, r.top, r.right, r.bottom);
}
@Override
public void setAlpha(int alpha) {
// TODO?
}
@Override
public void setColorFilter(ColorFilter cf) {
// TODO?
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public int getIntrinsicWidth() {
return size;
}
@Override
public int getIntrinsicHeight() {
return size;
}
}
}

View file

@ -1484,15 +1484,17 @@ public class XmppConnectionService extends Service {
}
updateMemorizingTrustManager();
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 7;
final int cacheSize = maxMemory / 8;
this.mDrawableCache = new LruCache<String, Drawable>(cacheSize) {
@Override
protected int sizeOf(final String key, final Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap == null) return 1024;
return bitmap.getByteCount() / 1024;
} else if (drawable instanceof AvatarService.TextDrawable) {
return 50;
} else {
return drawable.getIntrinsicWidth() * drawable.getIntrinsicHeight() * 40 / 1024;
}