1 package com.bumptech.glide.load.engine.prefill; 2 3 import android.graphics.Bitmap; 4 import android.os.Handler; 5 import android.os.Looper; 6 7 import com.bumptech.glide.load.DecodeFormat; 8 import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; 9 import com.bumptech.glide.load.engine.cache.MemoryCache; 10 import com.bumptech.glide.util.Util; 11 12 import java.util.HashMap; 13 import java.util.Map; 14 15 /** 16 * A class for pre-filling {@link android.graphics.Bitmap Bitmaps} in a 17 * {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}. 18 */ 19 public final class BitmapPreFiller { 20 21 private final MemoryCache memoryCache; 22 private final BitmapPool bitmapPool; 23 private final DecodeFormat defaultFormat; 24 private final Handler handler = new Handler(Looper.getMainLooper()); 25 26 private BitmapPreFillRunner current; 27 BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool, DecodeFormat defaultFormat)28 public BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool, DecodeFormat defaultFormat) { 29 this.memoryCache = memoryCache; 30 this.bitmapPool = bitmapPool; 31 this.defaultFormat = defaultFormat; 32 } 33 preFill(PreFillType.Builder... bitmapAttributeBuilders)34 public void preFill(PreFillType.Builder... bitmapAttributeBuilders) { 35 if (current != null) { 36 current.cancel(); 37 } 38 39 PreFillType[] bitmapAttributes = new PreFillType[bitmapAttributeBuilders.length]; 40 for (int i = 0; i < bitmapAttributeBuilders.length; i++) { 41 PreFillType.Builder builder = bitmapAttributeBuilders[i]; 42 if (builder.getConfig() == null) { 43 builder.setConfig(defaultFormat == DecodeFormat.ALWAYS_ARGB_8888 44 ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); 45 } 46 bitmapAttributes[i] = builder.build(); 47 } 48 49 PreFillQueue allocationOrder = generateAllocationOrder(bitmapAttributes); 50 current = new BitmapPreFillRunner(bitmapPool, memoryCache, allocationOrder); 51 handler.post(current); 52 } 53 54 // Visible for testing. generateAllocationOrder(PreFillType[] preFillSizes)55 PreFillQueue generateAllocationOrder(PreFillType[] preFillSizes) { 56 final int maxSize = memoryCache.getMaxSize() - memoryCache.getCurrentSize() + bitmapPool.getMaxSize(); 57 58 int totalWeight = 0; 59 for (PreFillType size : preFillSizes) { 60 totalWeight += size.getWeight(); 61 } 62 63 final float bytesPerWeight = maxSize / (float) totalWeight; 64 65 Map<PreFillType, Integer> attributeToCount = new HashMap<PreFillType, Integer>(); 66 for (PreFillType size : preFillSizes) { 67 int bytesForSize = Math.round(bytesPerWeight * size.getWeight()); 68 int bytesPerBitmap = getSizeInBytes(size); 69 int bitmapsForSize = bytesForSize / bytesPerBitmap; 70 attributeToCount.put(size, bitmapsForSize); 71 } 72 73 return new PreFillQueue(attributeToCount); 74 } 75 getSizeInBytes(PreFillType size)76 private static int getSizeInBytes(PreFillType size) { 77 return Util.getBitmapByteSize(size.getWidth(), size.getHeight(), size.getConfig()); 78 } 79 } 80 81