Home | History | Annotate | Download | only in data
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.photos.data;
     18 
     19 import android.graphics.Bitmap;
     20 import android.graphics.Point;
     21 import android.util.Pools.Pool;
     22 import android.util.Pools.SynchronizedPool;
     23 
     24 import com.android.photos.data.SparseArrayBitmapPool.Node;
     25 
     26 public class GalleryBitmapPool {
     27 
     28     private static final int CAPACITY_BYTES = 20971520;
     29     private static final int POOL_INDEX_NONE = -1;
     30     private static final int POOL_INDEX_SQUARE = 0;
     31     private static final int POOL_INDEX_PHOTO = 1;
     32     private static final int POOL_INDEX_MISC = 2;
     33 
     34     private static final Point[] COMMON_PHOTO_ASPECT_RATIOS =
     35         { new Point(4, 3), new Point(3, 2), new Point(16, 9) };
     36 
     37     private int mCapacityBytes;
     38     private SparseArrayBitmapPool [] mPools;
     39     private Pool<Node> mSharedNodePool = new SynchronizedPool<Node>(128);
     40 
     41     private GalleryBitmapPool(int capacityBytes) {
     42         mPools = new SparseArrayBitmapPool[3];
     43         mPools[POOL_INDEX_SQUARE] = new SparseArrayBitmapPool(capacityBytes / 3, mSharedNodePool);
     44         mPools[POOL_INDEX_PHOTO] = new SparseArrayBitmapPool(capacityBytes / 3, mSharedNodePool);
     45         mPools[POOL_INDEX_MISC] = new SparseArrayBitmapPool(capacityBytes / 3, mSharedNodePool);
     46         mCapacityBytes = capacityBytes;
     47     }
     48 
     49     private static GalleryBitmapPool sInstance = new GalleryBitmapPool(CAPACITY_BYTES);
     50 
     51     public static GalleryBitmapPool getInstance() {
     52         return sInstance;
     53     }
     54 
     55     private SparseArrayBitmapPool getPoolForDimensions(int width, int height) {
     56         int index = getPoolIndexForDimensions(width, height);
     57         if (index == POOL_INDEX_NONE) {
     58             return null;
     59         } else {
     60             return mPools[index];
     61         }
     62     }
     63 
     64     private int getPoolIndexForDimensions(int width, int height) {
     65         if (width <= 0 || height <= 0) {
     66             return POOL_INDEX_NONE;
     67         }
     68         if (width == height) {
     69             return POOL_INDEX_SQUARE;
     70         }
     71         int min, max;
     72         if (width > height) {
     73             min = height;
     74             max = width;
     75         } else {
     76             min = width;
     77             max = height;
     78         }
     79         for (Point ar : COMMON_PHOTO_ASPECT_RATIOS) {
     80             if (min * ar.x == max * ar.y) {
     81                 return POOL_INDEX_PHOTO;
     82             }
     83         }
     84         return POOL_INDEX_MISC;
     85     }
     86 
     87     public synchronized int getCapacity() {
     88         return mCapacityBytes;
     89     }
     90 
     91     public synchronized int getSize() {
     92         int total = 0;
     93         for (SparseArrayBitmapPool p : mPools) {
     94             total += p.getSize();
     95         }
     96         return total;
     97     }
     98 
     99     public Bitmap get(int width, int height) {
    100         SparseArrayBitmapPool pool = getPoolForDimensions(width, height);
    101         if (pool == null) {
    102             return null;
    103         } else {
    104             return pool.get(width, height);
    105         }
    106     }
    107 
    108     public boolean put(Bitmap b) {
    109         if (b == null || b.getConfig() != Bitmap.Config.ARGB_8888) {
    110             return false;
    111         }
    112         SparseArrayBitmapPool pool = getPoolForDimensions(b.getWidth(), b.getHeight());
    113         if (pool == null) {
    114             b.recycle();
    115             return false;
    116         } else {
    117             return pool.put(b);
    118         }
    119     }
    120 
    121     public void clear() {
    122         for (SparseArrayBitmapPool p : mPools) {
    123             p.clear();
    124         }
    125     }
    126 }
    127