diff options
author | nicolasroard <nicolasroard@google.com> | 2013-01-15 19:57:49 -0800 |
---|---|---|
committer | nicolasroard <nicolasroard@google.com> | 2013-01-22 16:05:42 -0800 |
commit | 0ad0346bfcff782759aaaadfd46bd0cfd9ef9f2c (patch) | |
tree | d918fd10cbccbe8b677109b33ab8379d8c8a9139 /src | |
parent | c9a9b3ad3ea46d11cb367221149cc515540d6688 (diff) | |
download | android_packages_apps_Snap-0ad0346bfcff782759aaaadfd46bd0cfd9ef9f2c.tar.gz android_packages_apps_Snap-0ad0346bfcff782759aaaadfd46bd0cfd9ef9f2c.tar.bz2 android_packages_apps_Snap-0ad0346bfcff782759aaaadfd46bd0cfd9ef9f2c.zip |
Better caching for RS filters
Change-Id: I78eaa90e408059cf1c59fc06920f5aef82ae2c0d
Diffstat (limited to 'src')
3 files changed, 79 insertions, 266 deletions
diff --git a/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java deleted file mode 100644 index 408ba5912..000000000 --- a/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.cache; - -import android.os.Handler; -import android.os.Handler.Callback; -import android.os.HandlerThread; -import android.os.Message; -import android.os.Process; - -public class DelayedPresetCache extends DirectPresetCache implements Callback { - private HandlerThread mHandlerThread = null; - - private final static int NEW_PRESET = 0; - private final static int COMPUTE_PRESET = 1; - - private Handler mProcessingHandler = null; - private final Handler mUIHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case NEW_PRESET: { - CachedPreset cache = (CachedPreset) msg.obj; - didCompute(cache); - break; - } - } - } - }; - - @Override - public boolean handleMessage(Message msg) { - switch (msg.what) { - case COMPUTE_PRESET: { - CachedPreset cache = (CachedPreset) msg.obj; - compute(cache); - Message uimsg = mUIHandler.obtainMessage(NEW_PRESET, cache); - mUIHandler.sendMessage(uimsg); - break; - } - } - return false; - } - - public DelayedPresetCache(ImageLoader loader, int size) { - super(loader, size); - mHandlerThread = new HandlerThread("ImageProcessing", Process.THREAD_PRIORITY_BACKGROUND); - mHandlerThread.start(); - mProcessingHandler = new Handler(mHandlerThread.getLooper(), this); - } - - @Override - protected void willCompute(CachedPreset cache) { - if (cache == null) { - return; - } - cache.setBusy(true); - Message msg = mProcessingHandler.obtainMessage(COMPUTE_PRESET, cache); - mProcessingHandler.sendMessage(msg); - } -} diff --git a/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java deleted file mode 100644 index d58e953c2..000000000 --- a/src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.cache; - -import android.graphics.Bitmap; - -import com.android.gallery3d.filtershow.imageshow.ImageShow; -import com.android.gallery3d.filtershow.imageshow.MasterImage; -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() { - mLoader.getActivity().runOnUiThread(mNotifyObserversRunnable); - } - - private final Runnable mNotifyObserversRunnable = new Runnable() { - @Override - public void run() { - for (int i = 0; i < mObservers.size(); i++) { - ImageShow imageShow = mObservers.elementAt(i); - // FIXME: need to replace the observer from ImageShow to - // MasterImage - if (imageShow != null) { - imageShow.invalidate(); - imageShow.updateImage(); - } - MasterImage.getImage().updatedCache(); - } - } - }; - - @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) { - CachedPreset cache = getCachedPreset(preset); - if (cache != null && !cache.mBusy) { - return cache.mBitmap; - } - 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) { - 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); - } - } - - } - -} diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java index 8f3938406..b571ec6ae 100644 --- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java +++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java @@ -96,6 +96,14 @@ public class ImagePreset { mDoApplyFilters = value; } + public boolean getDoApplyFilters() { + return mDoApplyFilters; + } + + public GeometryMetadata getGeometry() { + return mGeoData; + } + public boolean hasModifications() { if (mImageBorder != null && !mImageBorder.isNil()) { return true; @@ -165,10 +173,31 @@ public class ImagePreset { this.mImageLoader = mImageLoader; } + public boolean equals(ImagePreset preset) { + if (!same(preset)) { + return false; + } + if (mDoApplyFilters && preset.mDoApplyFilters) { + for (int i = 0; i < preset.mFilters.size(); i++) { + ImageFilter a = preset.mFilters.elementAt(i); + ImageFilter b = mFilters.elementAt(i); + if (!a.equals(b)) { + return false; + } + } + } + return true; + } + public boolean same(ImagePreset preset) { + if (preset == null) { + return false; + } + if (preset.mFilters.size() != mFilters.size()) { return false; } + if (!mName.equalsIgnoreCase(preset.name())) { return false; } @@ -207,6 +236,32 @@ public class ImagePreset { return true; } + public int nbFilters() { + return mFilters.size(); + } + + public int similarUpTo(ImagePreset preset) { + if (!mGeoData.equals(preset.mGeoData)) { + return -1; + } + + for (int i = 0; i < preset.mFilters.size(); i++) { + ImageFilter a = preset.mFilters.elementAt(i); + if (i < mFilters.size()) { + ImageFilter b = mFilters.elementAt(i); + if (!a.same(b)) { + return i; + } + if (a.getParameter() != b.getParameter()) { + return i; + } + } else { + return i; + } + } + return preset.mFilters.size(); + } + public String name() { return mName; } @@ -278,24 +333,40 @@ public class ImagePreset { } public Bitmap apply(Bitmap original) { - // First we apply any transform -- 90 rotate, flip, straighten, crop Bitmap bitmap = original; +// bitmap = applyGeometry(bitmap); + bitmap = applyFilters(bitmap, -1, -1); + return applyBorder(bitmap); + } + + public Bitmap applyGeometry(Bitmap bitmap) { + // Apply any transform -- 90 rotate, flip, straighten, crop + // Returns a new bitmap. + return mGeoData.apply(bitmap, mScaleFactor, mIsHighQuality); + } - if (mDoApplyGeometry) { - bitmap = mGeoData.apply(original, mScaleFactor, mIsHighQuality); + public Bitmap applyBorder(Bitmap bitmap) { + if (mImageBorder != null && mDoApplyGeometry) { + bitmap = mImageBorder.apply(bitmap, mScaleFactor, mIsHighQuality); } + return bitmap; + } + + public Bitmap applyFilters(Bitmap bitmap, int from, int to) { if (mDoApplyFilters) { - for (int i = 0; i < mFilters.size(); i++) { + if (from < 0) { + from = 0; + } + if (to == -1) { + to = mFilters.size(); + } + for (int i = from; i < to; i++) { ImageFilter filter = mFilters.elementAt(i); bitmap = filter.apply(bitmap, mScaleFactor, mIsHighQuality); } } - if (mImageBorder != null && mDoApplyGeometry) { - bitmap = mImageBorder.apply(bitmap, mScaleFactor, mIsHighQuality); - } - return bitmap; } |