Home | History | Annotate | Download | only in prefill
      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 
     28     public BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool, DecodeFormat defaultFormat) {
     29         this.memoryCache = memoryCache;
     30         this.bitmapPool = bitmapPool;
     31         this.defaultFormat = defaultFormat;
     32     }
     33 
     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.
     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 
     76     private static int getSizeInBytes(PreFillType size) {
     77         return Util.getBitmapByteSize(size.getWidth(), size.getHeight(), size.getConfig());
     78     }
     79 }
     80 
     81