BasicBitmapDrawable.java revision cea0c012d538f11b3ee97d4b7e78f4c1ea73d5be
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/* 25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * Copyright (C) 2013 The Android Open Source Project 35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * 45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * Licensed under the Apache License, Version 2.0 (the "License"); 5f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) * you may not use this file except in compliance with the License. 65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * You may obtain a copy of the License at 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * 85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * http://www.apache.org/licenses/LICENSE-2.0 95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * 105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * Unless required by applicable law or agreed to in writing, software 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * distributed under the License is distributed on an "AS IS" BASIS, 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu * See the License for the specific language governing permissions and 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * limitations under the License. 155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu */ 165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liupackage com.android.bitmap.drawable; 175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport android.content.res.Resources; 195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport android.graphics.Canvas; 205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport android.graphics.ColorFilter; 215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport android.graphics.Paint; 225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport android.graphics.PixelFormat; 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import android.graphics.Rect; 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import android.graphics.drawable.Drawable; 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import android.util.DisplayMetrics; 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import android.util.Log; 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport com.android.bitmap.BitmapCache; 295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuimport com.android.bitmap.DecodeTask; 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.DecodeTask.DecodeOptions; 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.NamedThreadFactory; 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.RequestKey; 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.ReusableBitmap; 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.util.BitmapUtils; 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.util.RectUtils; 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import com.android.bitmap.util.Trace; 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import java.util.concurrent.Executor; 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import java.util.concurrent.LinkedBlockingQueue; 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import java.util.concurrent.ThreadPoolExecutor; 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)import java.util.concurrent.TimeUnit; 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)/** 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * This class encapsulates the basic functionality needed to display a single image bitmap, 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * including request creation/cancelling, and data unbinding and re-binding. 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * <p> 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) * The actual bitmap decode work is handled by {@link DecodeTask}. 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) */ 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)public class BasicBitmapDrawable extends Drawable implements DecodeTask.DecodeCallback, 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Drawable.Callback { 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private RequestKey mCurrKey; 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private ReusableBitmap mBitmap; 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private final BitmapCache mCache; 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private final boolean mLimitDensity; 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private DecodeTask mTask; 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private int mDecodeWidth; 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private int mDecodeHeight; 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private static final String TAG = BasicBitmapDrawable.class.getSimpleName(); 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // based on framework CL:I015d77 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private static final int CORE_POOL_SIZE = CPU_COUNT + 1; 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private static final Executor SMALL_POOL_EXECUTOR = new ThreadPoolExecutor( 68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 1, TimeUnit.SECONDS, 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new LinkedBlockingQueue<Runnable>(128), new NamedThreadFactory("decode")); 70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private static final Executor EXECUTOR = SMALL_POOL_EXECUTOR; 72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private static final int MAX_BITMAP_DENSITY = DisplayMetrics.DENSITY_HIGH; 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private static final float VERTICAL_CENTER = 1f / 2; 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private final float mDensity; 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private final Paint mPaint = new Paint(); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private final Rect mSrcRect = new Rect(); 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private static final boolean DEBUG = DecodeTask.DEBUG; 82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public BasicBitmapDrawable(final Resources res, final BitmapCache cache, 84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final boolean limitDensity) { 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mDensity = res.getDisplayMetrics().density; 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mCache = cache; 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mLimitDensity = limitDensity; 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mPaint.setFilterBitmap(true); 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public RequestKey getKey() { 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return mCurrKey; 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) /** 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) * Set the dimensions to decode into. 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void setDecodeDimensions(int w, int h) { 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mDecodeWidth = w; 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mDecodeHeight = h; 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) decode(); 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void unbind() { 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) setImage(null); 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void bind(RequestKey key) { 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) setImage(key); 110cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private void setImage(final RequestKey key) { 113cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (mCurrKey != null && mCurrKey.equals(key)) { 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Trace.beginSection("set image"); 118cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Trace.beginSection("release reference"); 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (mBitmap != null) { 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mBitmap.releaseReference(); 121cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mBitmap = null; 122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Trace.endSection(); 124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mCurrKey = key; 125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (mTask != null) { 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mTask.cancel(); 128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mTask = null; 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (key == null) { 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) invalidateSelf(); 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Trace.endSection(); 134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 137cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // find cached entry here and skip decode if found. 138cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final ReusableBitmap cached = mCache.get(key, true /* incrementRefCount */); 139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (cached != null) { 140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) setBitmap(cached); 141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (DEBUG) { 142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Log.d(TAG, String.format("CACHE HIT key=%s", mCurrKey)); 143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) decode(); 146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (DEBUG) { 147cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Log.d(TAG, String.format( 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) "CACHE MISS key=%s\ncache=%s", mCurrKey, mCache.toDebugString())); 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Trace.endSection(); 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @Override 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void draw(final Canvas canvas) { 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final Rect bounds = getBounds(); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (bounds.isEmpty()) { 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (mBitmap != null && mBitmap.bmp != null) { 162cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BitmapUtils.calculateCroppedSrcRect( 163cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mBitmap.getLogicalWidth(), mBitmap.getLogicalHeight(), 164cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bounds.width(), bounds.height(), 165cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bounds.height(), Integer.MAX_VALUE, 166cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) VERTICAL_CENTER, false /* absoluteFraction */, 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1, mSrcRect); 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final int orientation = mBitmap.getOrientation(); 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // calculateCroppedSrcRect() gave us the source rectangle "as if" the orientation has 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // been corrected. We need to decode the uncorrected source rectangle. Calculate true 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // coordinates. 173cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RectUtils.rotateRectForOrientation(orientation, 174cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) new Rect(0, 0, mBitmap.getLogicalWidth(), mBitmap.getLogicalHeight()), 175cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mSrcRect); 176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // We may need to rotate the canvas, so we also have to rotate the bounds. 178cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final Rect rotatedBounds = new Rect(bounds); 179cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) RectUtils.rotateRect(orientation, bounds.centerX(), bounds.centerY(), rotatedBounds); 180cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 181cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Rotate the canvas. 182cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas.save(); 183cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas.rotate(orientation, bounds.centerX(), bounds.centerY()); 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas.drawBitmap(mBitmap.bmp, mSrcRect, rotatedBounds, mPaint); 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) canvas.restore(); 186cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @Override 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void setAlpha(int alpha) { 191cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final int old = mPaint.getAlpha(); 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mPaint.setAlpha(alpha); 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (alpha != old) { 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) invalidateSelf(); 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @Override 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void setColorFilter(ColorFilter cf) { 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) mPaint.setColorFilter(cf); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) invalidateSelf(); 202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu @Override 2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu public int getOpacity() { 2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return (mBitmap != null && (mBitmap.bmp.hasAlpha() || mPaint.getAlpha() < 255)) ? 207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) @Override 211cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public void onDecodeBegin(final RequestKey key) { } 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu @Override 214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public void onDecodeComplete(final RequestKey key, final ReusableBitmap result) { 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (key.equals(mCurrKey)) { 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu setBitmap(result); 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } else { 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // if the requests don't match (i.e. this request is stale), decrement the 2190de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // ref count to allow the bitmap to be pooled 2200de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) if (result != null) { 2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu result.releaseReference(); 222010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 223010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) @Override 227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public void onDecodeCancel(final RequestKey key) { } 2285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private void setBitmap(ReusableBitmap bmp) { 230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mBitmap != null && mBitmap != bmp) { 231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mBitmap.releaseReference(); 232cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu mBitmap = bmp; 234010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) invalidateSelf(); 235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu private void decode() { 2385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu final int bufferW; 239cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) final int bufferH; 240cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 241cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (mCurrKey == null) { 242cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 243cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 244cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 245cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Trace.beginSection("decode"); 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mLimitDensity) { 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) final float scale = 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Math.min(1f, (float) MAX_BITMAP_DENSITY / DisplayMetrics.DENSITY_DEFAULT 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu / mDensity); 2500de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) bufferW = (int) (mDecodeWidth * scale); 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bufferH = (int) (mDecodeHeight * scale); 252010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } else { 253010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bufferW = mDecodeWidth; 254010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bufferH = mDecodeHeight; 255010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 257010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (bufferW == 0 || bufferH == 0) { 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Trace.endSection(); 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) return; 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) if (mTask != null) { 262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mTask.cancel(); 263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) final DecodeOptions opts = new DecodeOptions(bufferW, bufferH, VERTICAL_CENTER, 2650de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) DecodeOptions.STRATEGY_ROUND_NEAREST); 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mTask = new DecodeTask(mCurrKey, opts, this, mCache); 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) mTask.executeOnExecutor(EXECUTOR); 268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Trace.endSection(); 269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) @Override 272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public void invalidateDrawable(Drawable who) { 273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) invalidateSelf(); 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 275010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) @Override 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public void scheduleDrawable(Drawable who, Runnable what, long when) { 278010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scheduleSelf(what, when); 279010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 280010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 281010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) @Override 282010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public void unscheduleDrawable(Drawable who, Runnable what) { 283010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) unscheduleSelf(what); 284010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) } 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 286010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)