summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java
blob: 7839ea2a3c06f0b912d4b609eaa2fadc72410746 (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

package com.android.gallery3d.filtershow.cache;

import android.graphics.Bitmap;

import com.android.gallery3d.filtershow.imageshow.ImageShow;
import com.android.gallery3d.filtershow.presets.ImagePreset;

import java.util.Vector;

public class DirectPresetCache implements Cache {

    private static final String LOGTAG = "DirectPresetCache";
    private Bitmap mOriginalBitmap = null;
    private final Vector<ImageShow> mObservers = new Vector<ImageShow>();
    private final Vector<CachedPreset> mCache = new Vector<CachedPreset>();
    private int mCacheSize = 1;
    private final Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
    private long mGlobalAge = 0;
    private ImageLoader mLoader = null;

    protected class CachedPreset {
        private Bitmap mBitmap = null;
        private ImagePreset mPreset = null;
        private long mAge = 0;
        private boolean mBusy = false;

        public void setBusy(boolean value) {
            mBusy = value;
        }

        public boolean busy() {
            return mBusy;
        }
    }

    public DirectPresetCache(ImageLoader loader, int size) {
        mLoader = loader;
        mCacheSize = size;
    }

    @Override
    public void setOriginalBitmap(Bitmap bitmap) {
        mOriginalBitmap = bitmap;
        notifyObservers();
    }

    public void notifyObservers() {
        for (int i = 0; i < mObservers.size(); i++) {
            ImageShow imageShow = mObservers.elementAt(i);
            imageShow.invalidate();
            imageShow.updateImage();
        }
    }

    @Override
    public void addObserver(ImageShow observer) {
        if (!mObservers.contains(observer)) {
            mObservers.add(observer);
        }
    }

    private CachedPreset getCachedPreset(ImagePreset preset) {
        for (int i = 0; i < mCache.size(); i++) {
            CachedPreset cache = mCache.elementAt(i);
            if (cache.mPreset == preset) {
                return cache;
            }
        }
        return null;
    }

    @Override
    public Bitmap get(ImagePreset preset) {
        // Log.v(LOGTAG, "get preset " + preset.name() + " : " + preset);
        CachedPreset cache = getCachedPreset(preset);
        if (cache != null && !cache.mBusy) {
            return cache.mBitmap;
        }
        // Log.v(LOGTAG, "didn't find preset " + preset.name() + " : " + preset
        // + " we have " + mCache.size() + " elts / " + mCacheSize);
        return null;
    }

    @Override
    public void reset(ImagePreset preset) {
        CachedPreset cache = getCachedPreset(preset);
        if (cache != null && !cache.mBusy) {
            cache.mBitmap = null;
            willCompute(cache);
        }
    }

    private CachedPreset getOldestCachedPreset() {
        CachedPreset found = null;
        for (int i = 0; i < mCache.size(); i++) {
            CachedPreset cache = mCache.elementAt(i);
            if (cache.mBusy) {
                continue;
            }
            if (found == null) {
                found = cache;
            } else {
                if (found.mAge > cache.mAge) {
                    found = cache;
                }
            }
        }
        return found;
    }

    protected void willCompute(CachedPreset cache) {
        if (cache == null) {
            return;
        }
        cache.mBusy = true;
        compute(cache);
        didCompute(cache);
    }

    protected void didCompute(CachedPreset cache) {
        cache.mBusy = false;
        notifyObservers();
    }

    protected void compute(CachedPreset cache) {
        cache.mBitmap = null;
        cache.mBitmap = mOriginalBitmap.copy(mBitmapConfig, true);
        float scaleFactor = (float) cache.mBitmap.getWidth() / (float) mLoader.getOriginalBounds().width();
        if (scaleFactor < 1.0f) {
            cache.mPreset.setIsHighQuality(false);
        }
        cache.mPreset.setScaleFactor(scaleFactor);
        cache.mBitmap = cache.mPreset.apply(cache.mBitmap);
        cache.mAge = mGlobalAge++;
    }

    @Override
    public void prepare(ImagePreset preset) {
        // Log.v(LOGTAG, "prepare preset " + preset.name() + " : " + preset);
        CachedPreset cache = getCachedPreset(preset);
        if (cache == null || (cache.mBitmap == null && !cache.mBusy)) {
            if (cache == null) {
                if (mCache.size() < mCacheSize) {
                    cache = new CachedPreset();
                    mCache.add(cache);
                } else {
                    cache = getOldestCachedPreset();
                }
            }
            if (cache != null) {
                cache.mPreset = preset;
                willCompute(cache);
            }
        }

    }

}