aboutsummaryrefslogtreecommitdiff
path: root/library/src/main/java/com/bumptech/glide/load/engine/prefill/BitmapPreFiller.java
blob: 4671a275534cad4f989b43e51024a248b5d72776 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.bumptech.glide.load.engine.prefill;

import android.graphics.Bitmap;
import android.os.Looper;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.engine.cache.MemoryCache;
import com.bumptech.glide.util.Util;

import java.util.HashMap;
import java.util.Map;

/**
 * A class for pre-filling {@link android.graphics.Bitmap Bitmaps} in a
 * {@link com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool}.
 */
public final class BitmapPreFiller {

    private final MemoryCache memoryCache;
    private final BitmapPool bitmapPool;
    private final DecodeFormat defaultFormat;

    private BitmapPreFillIdleHandler current;

    public BitmapPreFiller(MemoryCache memoryCache, BitmapPool bitmapPool, DecodeFormat defaultFormat) {
        this.memoryCache = memoryCache;
        this.bitmapPool = bitmapPool;
        this.defaultFormat = defaultFormat;
    }

    public void preFill(PreFillType.Builder... bitmapAttributeBuilders) {
        if (current != null) {
            current.cancel();
        }

        PreFillType[] bitmapAttributes = new PreFillType[bitmapAttributeBuilders.length];
        for (int i = 0; i < bitmapAttributeBuilders.length; i++) {
            PreFillType.Builder builder = bitmapAttributeBuilders[i];
            if (builder.getConfig() == null) {
                builder.setConfig(defaultFormat == DecodeFormat.ALWAYS_ARGB_8888
                        ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
            }
            bitmapAttributes[i] = builder.build();
        }

        PreFillQueue allocationOrder = generateAllocationOrder(bitmapAttributes);
        current = new BitmapPreFillIdleHandler(bitmapPool, memoryCache, allocationOrder);
        Looper.myQueue().addIdleHandler(current);
    }

    // Visible for testing.
    PreFillQueue generateAllocationOrder(PreFillType[] preFillSizes) {
        final int maxSize = memoryCache.getMaxSize() - memoryCache.getCurrentSize() + bitmapPool.getMaxSize();

        int totalWeight = 0;
        for (PreFillType size : preFillSizes) {
            totalWeight += size.getWeight();
        }

        final float bytesPerWeight = maxSize / (float) totalWeight;

        Map<PreFillType, Integer> attributeToCount = new HashMap<PreFillType, Integer>();
        for (PreFillType size : preFillSizes) {
            int bytesForSize = Math.round(bytesPerWeight * size.getWeight());
            int bytesPerBitmap = getSizeInBytes(size);
            int bitmapsForSize = bytesForSize / bytesPerBitmap;
            attributeToCount.put(size, bitmapsForSize);
        }

        return new PreFillQueue(attributeToCount);
    }

    private static int getSizeInBytes(PreFillType size) {
        return Util.getBitmapByteSize(size.getWidth(), size.getHeight(), size.getConfig());
    }
}