Skip to content

Commit f211b96

Browse files
falhassenglide-copybara-robot
authored andcommitted
This change introduces a mechanism in Glide's BitmapPool to prevent reusing bitmaps from the pool if the size difference between the requested bitmap and the available bitmap exceeds certain thresholds. The thresholds are defined by a maximum byte limit and a maximum ratio of wasted bytes to requested bytes.
The GlideBuilder now includes methods to set these waste limits. The LruPoolStrategy implementations (SizeConfigStrategy and SizeStrategy) are updated to check for excessive waste before returning a bitmap from the pool. If a bitmap is deemed too wasteful, it is not reused, and null is returned instead. PiperOrigin-RevId: 862444967
1 parent b12f574 commit f211b96

File tree

8 files changed

+82
-5
lines changed

8 files changed

+82
-5
lines changed

library/src/main/java/com/bumptech/glide/GlideBuilder.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ public RequestOptions build() {
6767
private boolean isActiveResourceRetentionAllowed;
6868
@Nullable private List<RequestListener<Object>> defaultRequestListeners;
6969

70+
private int bitmapPoolWasteLimit = 0;
71+
private float bitmapPoolWasteRatio = 0.0f;
72+
7073
/**
7174
* Sets the {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool} implementation to use
7275
* to store and retrieve reused {@link android.graphics.Bitmap}s.
@@ -523,6 +526,12 @@ public GlideBuilder setMemoryCategoryInBackground(MemoryCategory memoryCategory)
523526
return this;
524527
}
525528

529+
public GlideBuilder setBitmapPoolWasteLimit(int wasteLimit, float wasteRatio) {
530+
this.bitmapPoolWasteLimit = wasteLimit;
531+
this.bitmapPoolWasteRatio = wasteRatio;
532+
return this;
533+
}
534+
526535
/**
527536
* @deprecated This method does nothing. It will be hard coded and removed in a future release
528537
* without further warning.
@@ -593,6 +602,7 @@ Glide build(
593602
bitmapPool = new BitmapPoolAdapter();
594603
}
595604
}
605+
bitmapPool.setWasteLimit(bitmapPoolWasteLimit, bitmapPoolWasteRatio);
596606

597607
if (arrayPool == null) {
598608
arrayPool = new LruArrayPool(memorySizeCalculator.getArrayPoolSizeInBytes());

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/AttributeStrategy.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public int getSize(Bitmap bitmap) {
4747
return Util.getBitmapByteSize(bitmap);
4848
}
4949

50+
@Override
51+
public void setWasteLimit(int wasteLimit, float wasteRatio) {
52+
// Do nothing.
53+
}
54+
5055
@Override
5156
public String toString() {
5257
return "AttributeStrategy:\n " + groupedMap;

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPool.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,13 @@ public interface BitmapPool {
9797
* @see android.content.ComponentCallbacks2
9898
*/
9999
void trimMemory(int level);
100+
101+
/**
102+
* Sets the waste limit for the pool.
103+
*
104+
* @param wasteLimit The maximum number of bytes that can be wasted in the pool.
105+
* @param wasteRatio The maximum ratio of wasted bytes to requested bytes that can be wasted in
106+
* the pool.
107+
*/
108+
void setWasteLimit(int wasteLimit, float wasteRatio);
100109
}

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/BitmapPoolAdapter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,9 @@ public void clearMemory() {
4545
public void trimMemory(int level) {
4646
// Do nothing.
4747
}
48+
49+
@Override
50+
public void setWasteLimit(int wasteLimit, float wasteRatio) {
51+
// Do nothing.
52+
}
4853
}

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruBitmapPool.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ private static Set<Bitmap.Config> getDefaultAllowedConfigs() {
329329
return Collections.unmodifiableSet(configs);
330330
}
331331

332+
public void setWasteLimit(int wasteLimit, float wasteRatio) {
333+
strategy.setWasteLimit(wasteLimit, wasteRatio);
334+
}
335+
332336
private interface BitmapTracker {
333337
void add(Bitmap bitmap);
334338

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/LruPoolStrategy.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@ interface LruPoolStrategy {
1717
String logBitmap(int width, int height, Bitmap.Config config);
1818

1919
int getSize(Bitmap bitmap);
20+
21+
void setWasteLimit(int wasteLimit, float wasteRatio);
2022
}

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeConfigStrategy.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,15 @@ public class SizeConfigStrategy implements LruPoolStrategy {
5959
private final GroupedLinkedMap<Key, Bitmap> groupedMap = new GroupedLinkedMap<>();
6060
private final Map<Bitmap.Config, NavigableMap<Integer, Integer>> sortedSizes = new HashMap<>();
6161

62+
private int wasteLimit = 0;
63+
private float wasteRatio = 0.0f;
64+
65+
private boolean isWasteful(int requestSize, int actualSize) {
66+
int waste = actualSize - requestSize;
67+
return (wasteLimit > 0 && waste >= wasteLimit)
68+
|| (wasteRatio > 0 && waste / (float) requestSize >= wasteRatio);
69+
}
70+
6271
@Override
6372
public void put(Bitmap bitmap) {
6473
int size = Util.getBitmapByteSize(bitmap);
@@ -79,9 +88,15 @@ public Bitmap get(int width, int height, Bitmap.Config config) {
7988

8089
Bitmap result = groupedMap.get(bestKey);
8190
if (result != null) {
82-
// Decrement must be called before reconfigure.
83-
decrementBitmapOfSize(bestKey.size, result);
84-
result.reconfigure(width, height, config);
91+
// If the waste is too much, we put the bitmap back and return null.
92+
if (isWasteful(size, bestKey.size)) {
93+
groupedMap.put(bestKey, result);
94+
result = null;
95+
} else {
96+
// Decrement must be called before reconfigure.
97+
decrementBitmapOfSize(bestKey.size, result);
98+
result.reconfigure(width, height, config);
99+
}
85100
}
86101
return result;
87102
}
@@ -162,6 +177,12 @@ public int getSize(Bitmap bitmap) {
162177
return Util.getBitmapByteSize(bitmap);
163178
}
164179

180+
@Override
181+
public void setWasteLimit(int wasteLimit, float wasteRatio) {
182+
this.wasteLimit = wasteLimit;
183+
this.wasteRatio = wasteRatio;
184+
}
185+
165186
@Override
166187
public String toString() {
167188
StringBuilder sb =

library/src/main/java/com/bumptech/glide/load/engine/bitmap_recycle/SizeStrategy.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ final class SizeStrategy implements LruPoolStrategy {
2222
private final GroupedLinkedMap<Key, Bitmap> groupedMap = new GroupedLinkedMap<>();
2323
private final NavigableMap<Integer, Integer> sortedSizes = new PrettyPrintTreeMap<>();
2424

25+
int wasteLimit = 0;
26+
float wasteRatio = 0.0f;
27+
28+
private boolean isWasteful(int requestSize, int actualSize) {
29+
int waste = actualSize - requestSize;
30+
return (wasteLimit > 0 && waste >= wasteLimit)
31+
|| (wasteRatio > 0 && waste / (float) requestSize >= wasteRatio);
32+
}
33+
2534
@Override
2635
public void put(Bitmap bitmap) {
2736
int size = Util.getBitmapByteSize(bitmap);
@@ -49,8 +58,14 @@ public Bitmap get(int width, int height, Bitmap.Config config) {
4958
// lru pool
5059
final Bitmap result = groupedMap.get(key);
5160
if (result != null) {
52-
result.reconfigure(width, height, config);
53-
decrementBitmapOfSize(possibleSize);
61+
// If the waste is too much, we put the bitmap back and return null.
62+
if (isWasteful(size, possibleSize)) {
63+
groupedMap.put(key, result);
64+
return null;
65+
} else {
66+
result.reconfigure(width, height, config);
67+
decrementBitmapOfSize(possibleSize);
68+
}
5469
}
5570

5671
return result;
@@ -92,6 +107,12 @@ public int getSize(Bitmap bitmap) {
92107
return Util.getBitmapByteSize(bitmap);
93108
}
94109

110+
@Override
111+
public void setWasteLimit(int wasteLimit, float wasteRatio) {
112+
this.wasteLimit = wasteLimit;
113+
this.wasteRatio = wasteRatio;
114+
}
115+
95116
@Override
96117
public String toString() {
97118
return "SizeStrategy:\n " + groupedMap + "\n" + " SortedSizes" + sortedSizes;

0 commit comments

Comments
 (0)