15207906814e7f5983ce16db79affba28e5651d2eSam Juddpackage com.bumptech.glide.load.engine.prefill;
25207906814e7f5983ce16db79affba28e5651d2eSam Judd
335ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Juddimport android.graphics.Bitmap;
4dd737542dc2f6d58cfb1367929c8d3ebc1eeebf4Sam Juddimport android.os.Handler;
55207906814e7f5983ce16db79affba28e5651d2eSam Juddimport android.os.Looper;
6f7a6d65cf7c1a41908dd48e0dab68ee5b881387eSam Judd
735ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Juddimport com.bumptech.glide.load.DecodeFormat;
85207906814e7f5983ce16db79affba28e5651d2eSam Juddimport com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
95207906814e7f5983ce16db79affba28e5651d2eSam Juddimport com.bumptech.glide.load.engine.cache.MemoryCache;
105207906814e7f5983ce16db79affba28e5651d2eSam Juddimport com.bumptech.glide.util.Util;
115207906814e7f5983ce16db79affba28e5651d2eSam Judd
125207906814e7f5983ce16db79affba28e5651d2eSam Juddimport java.util.HashMap;
135207906814e7f5983ce16db79affba28e5651d2eSam Juddimport java.util.Map;
145207906814e7f5983ce16db79affba28e5651d2eSam Judd
155207906814e7f5983ce16db79affba28e5651d2eSam Judd/**
165207906814e7f5983ce16db79affba28e5651d2eSam Judd * A class for pre-filling {@link android.graphics.Bitmap Bitmaps} in a
175207906814e7f5983ce16db79affba28e5651d2eSam Judd * {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}.
185207906814e7f5983ce16db79affba28e5651d2eSam Judd */
195207906814e7f5983ce16db79affba28e5651d2eSam Juddpublic final class BitmapPreFiller {
205207906814e7f5983ce16db79affba28e5651d2eSam Judd
215207906814e7f5983ce16db79affba28e5651d2eSam Judd    private final MemoryCache memoryCache;
225207906814e7f5983ce16db79affba28e5651d2eSam Judd    private final BitmapPool bitmapPool;
2335ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd    private final DecodeFormat defaultFormat;
24dd737542dc2f6d58cfb1367929c8d3ebc1eeebf4Sam Judd    private final Handler handler = new Handler(Looper.getMainLooper());
255207906814e7f5983ce16db79affba28e5651d2eSam Judd
26dd737542dc2f6d58cfb1367929c8d3ebc1eeebf4Sam Judd    private BitmapPreFillRunner current;
275207906814e7f5983ce16db79affba28e5651d2eSam Judd
2835ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd    public BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool, DecodeFormat defaultFormat) {
295207906814e7f5983ce16db79affba28e5651d2eSam Judd        this.memoryCache = memoryCache;
305207906814e7f5983ce16db79affba28e5651d2eSam Judd        this.bitmapPool = bitmapPool;
3135ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        this.defaultFormat = defaultFormat;
325207906814e7f5983ce16db79affba28e5651d2eSam Judd    }
335207906814e7f5983ce16db79affba28e5651d2eSam Judd
3435ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd    public void preFill(PreFillType.Builder... bitmapAttributeBuilders) {
355207906814e7f5983ce16db79affba28e5651d2eSam Judd        if (current != null) {
365207906814e7f5983ce16db79affba28e5651d2eSam Judd            current.cancel();
375207906814e7f5983ce16db79affba28e5651d2eSam Judd        }
3835ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd
3935ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        PreFillType[] bitmapAttributes = new PreFillType[bitmapAttributeBuilders.length];
4035ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        for (int i = 0; i < bitmapAttributeBuilders.length; i++) {
4135ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd            PreFillType.Builder builder = bitmapAttributeBuilders[i];
4235ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd            if (builder.getConfig() == null) {
4335ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd                builder.setConfig(defaultFormat == DecodeFormat.ALWAYS_ARGB_8888
4435ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd                        ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
4535ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd            }
4635ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd            bitmapAttributes[i] = builder.build();
4735ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        }
4835ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd
495207906814e7f5983ce16db79affba28e5651d2eSam Judd        PreFillQueue allocationOrder = generateAllocationOrder(bitmapAttributes);
50dd737542dc2f6d58cfb1367929c8d3ebc1eeebf4Sam Judd        current = new BitmapPreFillRunner(bitmapPool, memoryCache, allocationOrder);
51dd737542dc2f6d58cfb1367929c8d3ebc1eeebf4Sam Judd        handler.post(current);
525207906814e7f5983ce16db79affba28e5651d2eSam Judd    }
535207906814e7f5983ce16db79affba28e5651d2eSam Judd
545207906814e7f5983ce16db79affba28e5651d2eSam Judd    // Visible for testing.
5535ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd    PreFillQueue generateAllocationOrder(PreFillType[] preFillSizes) {
565ba19a0e69ad3a651b8f13ba45de48a56b56ce36Sam Judd        final int maxSize = memoryCache.getMaxSize() - memoryCache.getCurrentSize() + bitmapPool.getMaxSize();
575207906814e7f5983ce16db79affba28e5651d2eSam Judd
585207906814e7f5983ce16db79affba28e5651d2eSam Judd        int totalWeight = 0;
5935ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        for (PreFillType size : preFillSizes) {
605207906814e7f5983ce16db79affba28e5651d2eSam Judd            totalWeight += size.getWeight();
615207906814e7f5983ce16db79affba28e5651d2eSam Judd        }
625207906814e7f5983ce16db79affba28e5651d2eSam Judd
635207906814e7f5983ce16db79affba28e5651d2eSam Judd        final float bytesPerWeight = maxSize / (float) totalWeight;
645207906814e7f5983ce16db79affba28e5651d2eSam Judd
6535ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        Map<PreFillType, Integer> attributeToCount = new HashMap<PreFillType, Integer>();
6635ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd        for (PreFillType size : preFillSizes) {
675207906814e7f5983ce16db79affba28e5651d2eSam Judd            int bytesForSize = Math.round(bytesPerWeight * size.getWeight());
685207906814e7f5983ce16db79affba28e5651d2eSam Judd            int bytesPerBitmap = getSizeInBytes(size);
695207906814e7f5983ce16db79affba28e5651d2eSam Judd            int bitmapsForSize = bytesForSize / bytesPerBitmap;
705207906814e7f5983ce16db79affba28e5651d2eSam Judd            attributeToCount.put(size, bitmapsForSize);
715207906814e7f5983ce16db79affba28e5651d2eSam Judd        }
725207906814e7f5983ce16db79affba28e5651d2eSam Judd
735207906814e7f5983ce16db79affba28e5651d2eSam Judd        return new PreFillQueue(attributeToCount);
745207906814e7f5983ce16db79affba28e5651d2eSam Judd    }
755207906814e7f5983ce16db79affba28e5651d2eSam Judd
7635ba01c93ca9ff3ed3b9943571a746c5cb242a24Sam Judd    private static int getSizeInBytes(PreFillType size) {
7720676c43a1900854678149f8b0b8184962c383daSam Judd        return Util.getBitmapByteSize(size.getWidth(), size.getHeight(), size.getConfig());
785207906814e7f5983ce16db79affba28e5651d2eSam Judd    }
795207906814e7f5983ce16db79affba28e5651d2eSam Judd}
805207906814e7f5983ce16db79affba28e5651d2eSam Judd
81