Home | History | Annotate | Download | only in bitmap
      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.bitmap;
     18 
     19 import com.android.mail.utils.LogTag;
     20 import com.android.mail.utils.LogUtils;
     21 
     22 /**
     23  * This subclass provides custom pool behavior. The pool can be set to block on {@link #poll()} if
     24  * nothing can be returned. This is useful if you know you will incur high costs upon receiving
     25  * nothing from the pool, and you do not want to incur those costs at the critical moment when the
     26  * UI is animating.
     27  */
     28 public class AltBitmapCache extends AltPooledCache<DecodeTask.Request, ReusableBitmap>
     29         implements BitmapCache {
     30     private boolean mBlocking = false;
     31     private final Object mLock = new Object();
     32 
     33     private final static boolean DEBUG = false;
     34     private final static String TAG = LogTag.getLogTag();
     35 
     36     public AltBitmapCache(final int targetSizeBytes, final float nonPooledFraction) {
     37         super(targetSizeBytes, nonPooledFraction);
     38     }
     39 
     40     /**
     41      * Declare that {@link #poll()} should now block until it can return something.
     42      */
     43     public void setBlocking(final boolean blocking) {
     44         synchronized (mLock) {
     45             if (DEBUG) LogUtils.d(TAG, "AltBitmapCache: block %b", blocking);
     46             mBlocking = blocking;
     47             if (!mBlocking) {
     48                 // no longer blocking. Notify every thread.
     49                 mLock.notifyAll();
     50             }
     51         }
     52     }
     53 
     54     @Override
     55     protected int sizeOf(final ReusableBitmap value) {
     56         return value.getByteCount();
     57     }
     58 
     59     /**
     60      * If {@link #setBlocking(boolean)} has been called with true, this method will block until a
     61      * resource is available.
     62      * @return an available resource, or null if none are available. Null will never be returned
     63      * until blocking is set to false.
     64      */
     65     @Override
     66     public ReusableBitmap poll() {
     67         ReusableBitmap bitmap;
     68         synchronized (mLock) {
     69             while ((bitmap = super.poll()) == null && mBlocking) {
     70                 if (DEBUG) {
     71                     LogUtils.d(TAG, "AltBitmapCache: %s waiting", Thread.currentThread().getName());
     72                 }
     73                 Trace.beginSection("sleep");
     74                 try {
     75                     // block
     76                     mLock.wait();
     77                     if (DEBUG) {
     78                         LogUtils.d(TAG, "AltBitmapCache: %s notified",
     79                                 Thread.currentThread().getName());
     80                     }
     81                 } catch (InterruptedException e) {
     82                 }
     83                 Trace.endSection();
     84             }
     85         }
     86         return bitmap;
     87     }
     88 
     89     @Override
     90     public void offer(final ReusableBitmap value) {
     91         synchronized (mLock) {
     92             super.offer(value);
     93             if (DEBUG) LogUtils.d(TAG, "AltBitmapCache: offer +1");
     94             // new resource gained. Notify one thread.
     95             mLock.notify();
     96         }
     97     }
     98 }
     99