19fc12334a7d14347cd6951d0653264b2597bd3a0Sam Juddpackage com.bumptech.glide.load.engine.bitmap_recycle;
2cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
3cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Juddimport android.graphics.Bitmap;
4cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
5a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Juddimport java.util.LinkedList;
6a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Juddimport java.util.Map;
7e9bb38b983ede3ce22220af5de3ba803c50248c8Sam Juddimport java.util.WeakHashMap;
8cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
9a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Juddpublic class SerialBitmapReferenceCounter implements BitmapReferenceCounter {
10cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
112a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private static class InnerTrackerPool {
12a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        private LinkedList<InnerTracker> pool = new LinkedList<InnerTracker>();
13cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
142a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public InnerTracker get() {
152a2882e26b572d6d69939ac553cd840059caee3aSam Judd            InnerTracker result = pool.poll();
162a2882e26b572d6d69939ac553cd840059caee3aSam Judd            if (result == null) {
172a2882e26b572d6d69939ac553cd840059caee3aSam Judd                result = new InnerTracker();
182a2882e26b572d6d69939ac553cd840059caee3aSam Judd            }
19cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
202a2882e26b572d6d69939ac553cd840059caee3aSam Judd            return result;
21cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
22cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
232a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public void release(InnerTracker innerTracker) {
242a2882e26b572d6d69939ac553cd840059caee3aSam Judd            pool.offer(innerTracker);
25cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
26cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd    }
27cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
282a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private static class InnerTracker {
29a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        private int refs = 0;
30cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
312a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public void acquire() {
32a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd            refs++;
33cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
34cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
352a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public boolean release() {
36a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd            refs--;
37cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
382a2882e26b572d6d69939ac553cd840059caee3aSam Judd            return refs == 0;
392a2882e26b572d6d69939ac553cd840059caee3aSam Judd        }
402a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
41cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
42e9bb38b983ede3ce22220af5de3ba803c50248c8Sam Judd    private final Map<Bitmap, InnerTracker> counter = new WeakHashMap<Bitmap, InnerTracker>();
439b2c9802d9eb0fb9aaa25388ad064a41b95186afSam Judd    private final BitmapPool target;
442a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private final InnerTrackerPool pool = new InnerTrackerPool();
45cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
46a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd    public SerialBitmapReferenceCounter(BitmapPool target) {
472a2882e26b572d6d69939ac553cd840059caee3aSam Judd        this.target = target;
482a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
492a2882e26b572d6d69939ac553cd840059caee3aSam Judd
50ba5282d0a246a9529d615ca35521a71a98009f5eSam Judd    private void initBitmap(Bitmap toInit) {
51a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        final InnerTracker tracker = counter.get(toInit);
52a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        if (tracker == null) {
53a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd            counter.put(toInit, pool.get());
5458ba89d87f7dc53dd734f32db1cc9c3d56027f44Sam Judd        }
552a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
562a2882e26b572d6d69939ac553cd840059caee3aSam Judd
57e356a4f7ddc93843f8a28d810ff4c8777032411cSam Judd    @Override
582a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void acquireBitmap(Bitmap bitmap) {
59ba5282d0a246a9529d615ca35521a71a98009f5eSam Judd        initBitmap(bitmap);
60a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        counter.get(bitmap).acquire();
612a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
62cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
63e356a4f7ddc93843f8a28d810ff4c8777032411cSam Judd    @Override
642a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void releaseBitmap(Bitmap bitmap) {
65a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        final InnerTracker tracker = counter.get(bitmap);
662a2882e26b572d6d69939ac553cd840059caee3aSam Judd        if (tracker.release()) {
672a2882e26b572d6d69939ac553cd840059caee3aSam Judd            recycle(tracker, bitmap);
68cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
692a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
70cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
712a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private void recycle(InnerTracker tracker, Bitmap bitmap) {
72387872f47a801102dba3d47250f82839976108e1Sam Judd        if (!target.put(bitmap)) {
73387872f47a801102dba3d47250f82839976108e1Sam Judd            bitmap.recycle();
74387872f47a801102dba3d47250f82839976108e1Sam Judd        }
75a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        counter.remove(bitmap);
76a967562c5c0d2f31bb79e344240f2e0e0ee37721Sam Judd        pool.release(tracker);
77cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd    }
78cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd}
79