Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec1e009a authored by nicolasroard's avatar nicolasroard
Browse files

Improves memory management

Also adds some debugging tracking tools.

bug:10112287

Change-Id: I3f9b3d173db99818e5c9ae9a62b0ec38cd2b341b
parent 34cfdfcd
Loading
Loading
Loading
Loading
+96 −7
Original line number Diff line number Diff line
@@ -32,8 +32,85 @@ public class BitmapCache {
            mBitmapCache = new HashMap<Long, ArrayList<WeakReference<Bitmap>>>();
    private final int mMaxItemsPerKey = 4;

    private static final boolean DEBUG = false;
    private CacheProcessing mCacheProcessing;

    public final static int PREVIEW_CACHE = 1;
    public final static int NEW_LOOK = 2;
    public final static int ICON = 3;
    public final static int FILTERS = 4;
    public final static int GEOMETRY = 5;
    public final static int HIGHRES = 6;
    public final static int UTIL_GEOMETRY = 7;
    public final static int RENDERING_REQUEST = 8;
    public final static int REGION = 9;
    public final static int TINY_PLANET = 10;
    public final static int PREVIEW_CACHE_NO_FILTERS = 11;
    public final static int PREVIEW_CACHE_NO_ROOT = 12;
    public static final int PREVIEW_CACHE_NO_APPLY = 13;
    public final static int TRACKING_COUNT = 14;
    private int[] mTracking = new int[TRACKING_COUNT];

    class BitmapTracking {
        Bitmap bitmap;
        int type;
    }

    private ArrayList<BitmapTracking> mBitmapTracking = new ArrayList<BitmapTracking>();

    private void track(Bitmap bitmap, int type) {
        for (int i = 0; i < mBitmapTracking.size(); i++) {
            BitmapTracking tracking = mBitmapTracking.get(i);
            if (tracking.bitmap == bitmap) {
                Log.e(LOGTAG, "giving a bitmap already given!!!");
            }
        }
        BitmapTracking tracking = new BitmapTracking();
        tracking.bitmap = bitmap;
        tracking.type = type;
        mBitmapTracking.add(tracking);
        mTracking[tracking.type] ++;
    }

    private void untrack(Bitmap bitmap) {
        for (int i = 0; i < mBitmapTracking.size(); i++) {
            BitmapTracking tracking = mBitmapTracking.get(i);
            if (tracking.bitmap == bitmap) {
                mTracking[tracking.type] --;
                mBitmapTracking.remove(i);
                return;
            }
        }
    }

    public String getTrackingName(int i) {
        switch (i) {
            case PREVIEW_CACHE: return "PREVIEW_CACHE";
            case PREVIEW_CACHE_NO_FILTERS: return "PREVIEW_CACHE_NO_FILTERS";
            case PREVIEW_CACHE_NO_ROOT: return "PREVIEW_CACHE_NO_ROOT";
            case PREVIEW_CACHE_NO_APPLY: return "PREVIEW_CACHE_NO_APPLY";
            case NEW_LOOK: return "NEW_LOOK";
            case ICON: return "ICON";
            case FILTERS: return "FILTERS";
            case GEOMETRY: return "GEOMETRY";
            case HIGHRES: return "HIGHRES";
            case UTIL_GEOMETRY: return "UTIL_GEOMETRY";
            case RENDERING_REQUEST: return "RENDERING_REQUEST";
            case REGION: return "REGION";
            case TINY_PLANET: return "TINY_PLANET";
        }
        return "UNKNOWN";
    }

    public void showBitmapCounts() {
        Log.v(LOGTAG, "\n showBitmap ---- ");
        for (int i = 0; i < TRACKING_COUNT; i++) {
            if (mTracking[i] != 0) {
                Log.v(LOGTAG, getTrackingName(i) + " => " + mTracking[i]);
            }
        }
    }

    public void setCacheProcessing(CacheProcessing cache) {
        mCacheProcessing = cache;
    }
@@ -46,13 +123,16 @@ public class BitmapCache {
        cache(bitmap);
    }

    public synchronized void cache(Bitmap bitmap) {
    public synchronized boolean cache(Bitmap bitmap) {
        if (bitmap == null) {
            return;
            return true;
        }
        if (mCacheProcessing != null && mCacheProcessing.contains(bitmap)) {
            Log.e(LOGTAG, "Trying to cache a bitmap still used in the pipeline");
            return;
            return false;
        }
        if (DEBUG) {
            untrack(bitmap);
        }
        Long key = calcKey(bitmap.getWidth(), bitmap.getHeight());
        ArrayList<WeakReference<Bitmap>> list = mBitmapCache.get(key);
@@ -77,14 +157,15 @@ public class BitmapCache {
            for (i = 0; i < list.size(); i++) {
                WeakReference<Bitmap> ref = list.get(i);
                if (ref.get() == bitmap) {
                    return; // bitmap already in the cache
                    return true; // bitmap already in the cache
                }
            }
            list.add(new WeakReference<Bitmap>(bitmap));
        }
        return true;
    }

    public synchronized Bitmap getBitmap(int w, int h) {
    public synchronized Bitmap getBitmap(int w, int h, int type) {
        Long key = calcKey(w, h);
        WeakReference<Bitmap> ref = null;
        ArrayList<WeakReference<Bitmap>> list = mBitmapCache.get(key);
@@ -103,12 +184,20 @@ public class BitmapCache {
                || bitmap.getHeight() != h) {
            bitmap = Bitmap.createBitmap(
                    w, h, Bitmap.Config.ARGB_8888);
            showBitmapCounts();
        }

        if (DEBUG) {
            track(bitmap, type);
            if (mCacheProcessing != null && mCacheProcessing.contains(bitmap)) {
                Log.e(LOGTAG, "Trying to give a bitmap used in the pipeline");
            }
        }
        return bitmap;
    }

    public Bitmap getBitmapCopy(Bitmap source) {
        Bitmap bitmap = getBitmap(source.getWidth(), source.getHeight());
    public synchronized Bitmap getBitmapCopy(Bitmap source, int type) {
        Bitmap bitmap = getBitmap(source.getWidth(), source.getHeight(), type);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawBitmap(source, 0, 0, null);
        return bitmap;
+4 −2
Original line number Diff line number Diff line
@@ -253,14 +253,16 @@ public final class ImageLoader {
            if (!r.contains(imageBounds)) {
                imageBounds.intersect(r);
            }
            Bitmap reuse = environment.getBitmap(imageBounds.width(), imageBounds.height());
            Bitmap reuse = environment.getBitmap(imageBounds.width(),
                    imageBounds.height(), BitmapCache.REGION);
            options.inBitmap = reuse;
            Bitmap bitmap = decoder.decodeRegion(imageBounds, options);
            if (bitmap != reuse) {
                environment.cache(reuse); // not reused, put back in cache
            }
            if (imageBounds.width() != bounds.width() || imageBounds.height() != bounds.height()) {
                Bitmap temp = environment.getBitmap(bounds.width(), bounds.height());
                Bitmap temp = environment.getBitmap(bounds.width(),
                        bounds.height(), BitmapCache.REGION);
                Canvas canvas = new Canvas(temp);
                canvas.drawARGB(0, 0, 0, 0);
                float dx = imageBounds.left - bounds.left;
+3 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.graphics.RectF;
import com.adobe.xmp.XMPException;
import com.adobe.xmp.XMPMeta;
import com.android.gallery3d.app.Log;
import com.android.gallery3d.filtershow.cache.BitmapCache;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.pipeline.ImagePreset;
@@ -92,7 +93,8 @@ public class ImageFilterTinyPlanet extends SimpleImageFilter {
        }
        while (mBitmapOut == null) {
            try {
                mBitmapOut = getEnvironment().getBitmap(outputSize, outputSize);
                mBitmapOut = getEnvironment().getBitmap(outputSize,
                        outputSize, BitmapCache.TINY_PLANET);
            } catch (java.lang.OutOfMemoryError e) {
                System.gc();
                outputSize /= 2;
+2 −1
Original line number Diff line number Diff line
@@ -317,7 +317,8 @@ public final class GeometryMathUtils {
        Matrix m = getCropSelectionToScreenMatrix(null, holder, width, height, frame.width(),
                frame.height());
        BitmapCache bitmapCache = MasterImage.getImage().getBitmapCache();
        Bitmap temp = bitmapCache.getBitmap(frame.width(), frame.height());
        Bitmap temp = bitmapCache.getBitmap(frame.width(),
                frame.height(), BitmapCache.UTIL_GEOMETRY);
        Canvas canvas = new Canvas(temp);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
+2 −2
Original line number Diff line number Diff line
@@ -419,7 +419,6 @@ public class MasterImage implements RenderingRequestCaller {
    }

    public void onNewLook(FilterRepresentation newRepresentation) {
        getBitmapCache().cache(mPreviousImage);
        if (getFilteredImage() == null) {
            return;
        }
@@ -429,7 +428,8 @@ public class MasterImage implements RenderingRequestCaller {
                mCurrentAnimRotationStartValue += 90;
            }
        } else {
            mPreviousImage = getBitmapCache().getBitmapCopy(getFilteredImage());
            resetAnimBitmap();
            mPreviousImage = mBitmapCache.getBitmapCopy(getFilteredImage(), BitmapCache.NEW_LOOK);
        }
        mPreviousPreset = getPreviewBuffer().getConsumer().getPreset();
        if (newRepresentation instanceof FilterUserPresetRepresentation) {
Loading