OSDN Git Service

Better caching for RS filters
authornicolasroard <nicolasroard@google.com>
Wed, 16 Jan 2013 03:57:49 +0000 (19:57 -0800)
committernicolasroard <nicolasroard@google.com>
Wed, 23 Jan 2013 00:05:42 +0000 (16:05 -0800)
Change-Id: I78eaa90e408059cf1c59fc06920f5aef82ae2c0d

src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java [deleted file]
src/com/android/gallery3d/filtershow/cache/DirectPresetCache.java [deleted file]
src/com/android/gallery3d/filtershow/presets/ImagePreset.java

diff --git a/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java b/src/com/android/gallery3d/filtershow/cache/DelayedPresetCache.java
deleted file mode 100644 (file)
index 408ba59..0000000
+++ /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 (file)
index d58e953..0000000
+++ /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);
-            }
-        }
-
-    }
-
-}
index 8f39384..b571ec6 100644 (file)
@@ -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;
     }