summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authornicolasroard <nicolasroard@google.com>2013-01-15 19:57:49 -0800
committernicolasroard <nicolasroard@google.com>2013-01-22 16:05:42 -0800
commit0ad0346bfcff782759aaaadfd46bd0cfd9ef9f2c (patch)
treed918fd10cbccbe8b677109b33ab8379d8c8a9139 /src
parentc9a9b3ad3ea46d11cb367221149cc515540d6688 (diff)
downloadandroid_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')
-rw-r--r--src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java75
-rw-r--r--src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java183
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePreset.java87
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;
}