OSDN Git Service

Stopgap fixes for more of the photo editor's memory issues.
authorRuben Brunk <rubenbrunk@google.com>
Fri, 22 Feb 2013 21:25:51 +0000 (13:25 -0800)
committerRuben Brunk <rubenbrunk@google.com>
Fri, 22 Feb 2013 21:54:37 +0000 (13:54 -0800)
Bug: 8253109
Bug: 8233895
Change-Id: Idd55618807ff0a0c5ac0cbb8c71db167fa32e70b

src/com/android/gallery3d/filtershow/FilterShowActivity.java
src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
src/com/android/gallery3d/filtershow/cache/ImageLoader.java
src/com/android/gallery3d/filtershow/filters/ImageFilter.java
src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java

index 7e8a3f5..fd30ac0 100644 (file)
@@ -152,6 +152,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
+        ImageFilter.setActivityForMemoryToasts(this);
         setResources();
 
         Resources res = getResources();
@@ -520,6 +521,9 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
         if (mLoadBitmapTask != null) {
             mLoadBitmapTask.cancel(false);
         }
+        MasterImage.reset();
+        FilteringPipeline.reset();
+        ImageFilter.resetStatics();
         super.onDestroy();
     }
 
index 7d5b529..0af4063 100644 (file)
@@ -31,7 +31,7 @@ import com.android.gallery3d.filtershow.presets.ImagePreset;
 
 public class FilteringPipeline implements Handler.Callback {
 
-    private final static FilteringPipeline gPipeline = new FilteringPipeline();
+    private static FilteringPipeline sPipeline;
     private static final String LOGTAG = "FilteringPipeline";
     private ImagePreset mPreviousGeometryPreset = null;
     private ImagePreset mPreviousFiltersPreset = null;
@@ -117,7 +117,10 @@ public class FilteringPipeline implements Handler.Callback {
     }
 
     public static FilteringPipeline getPipeline() {
-        return gPipeline;
+        if (sPipeline == null) {
+            sPipeline = new FilteringPipeline();
+        }
+        return sPipeline;
     }
 
     public synchronized void setOriginal(Bitmap bitmap) {
@@ -337,4 +340,8 @@ public class FilteringPipeline implements Handler.Callback {
     public float getPreviewScaleFactor() {
         return mPreviewScaleFactor;
     }
+
+    public static void reset() {
+        sPipeline = null;
+    }
 }
index 25bb6b6..a5b1bc5 100644 (file)
@@ -62,6 +62,8 @@ import java.io.OutputStream;
 import java.util.Vector;
 import java.util.concurrent.locks.ReentrantLock;
 
+
+// TODO: this class has waaaay to much bitmap copying.  Cleanup.
 public class ImageLoader {
 
     private static final String LOGTAG = "ImageLoader";
@@ -389,15 +391,13 @@ public class ImageLoader {
             }
             bmp = loadRegionBitmap(mUri, options, bounds);
             if (bmp != null) {
-                // TODO: this workaround for RS might not be needed ultimately
-                Bitmap bmp2 = bmp.copy(Bitmap.Config.ARGB_8888, true);
                 float scaleFactor = imagePreset.getScaleFactor();
                 imagePreset.setScaleFactor(1.0f);
-                bmp2 = imagePreset.apply(bmp2);
+                bmp = imagePreset.apply(bmp);
                 imagePreset.setScaleFactor(scaleFactor);
-                mZoomCache.setImage(imagePreset, bounds, bmp2);
+                mZoomCache.setImage(imagePreset, bounds, bmp);
                 mLoadingLock.unlock();
-                return bmp2;
+                return bmp;
             }
         }
         mLoadingLock.unlock();
index 614c6a0..1b7a367 100644 (file)
@@ -18,8 +18,10 @@ package com.android.gallery3d.filtershow.filters;
 
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
+import android.widget.Toast;
 
 import com.android.gallery3d.R;
+import com.android.gallery3d.filtershow.FilterShowActivity;
 import com.android.gallery3d.filtershow.editors.BasicEditor;
 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
 import com.android.gallery3d.filtershow.presets.ImagePreset;
@@ -31,6 +33,30 @@ public abstract class ImageFilter implements Cloneable {
     protected String mName = "Original";
     private final String LOGTAG = "ImageFilter";
 
+    // TODO: Temporary, for dogfood note memory issues with toasts for better
+    // feedback. Remove this when filters actually work in low memory
+    // situations.
+    private static FilterShowActivity sActivity = null;
+
+    public static void setActivityForMemoryToasts(FilterShowActivity activity) {
+        sActivity = activity;
+    }
+
+    public static void resetStatics() {
+        sActivity = null;
+    }
+
+    public void displayLowMemoryToast() {
+        if (sActivity != null) {
+            sActivity.runOnUiThread(new Runnable() {
+                public void run() {
+                    Toast.makeText(sActivity, "Memory too low for filter " + getName() +
+                            ", please file a bug report", Toast.LENGTH_SHORT).show();
+                }
+            });
+        }
+    }
+
     public void setName(String name) {
         mName = name;
     }
@@ -45,8 +71,8 @@ public abstract class ImageFilter implements Cloneable {
     }
 
     /**
-     * Called on small bitmaps to create button icons for each filter.
-     * Override this to provide filter-specific button icons.
+     * Called on small bitmaps to create button icons for each filter. Override
+     * this to provide filter-specific button icons.
      */
     public Bitmap iconApply(Bitmap bitmap, float scaleFactor, int quality) {
         return apply(bitmap, scaleFactor, quality);
index 74712be..a3467ed 100644 (file)
@@ -89,6 +89,11 @@ public abstract class ImageFilterRS extends ImageFilter {
             Log.e(LOGTAG, "Illegal argument? " + e);
         } catch (android.renderscript.RSRuntimeException e) {
             Log.e(LOGTAG, "RS runtime exception ? " + e);
+        } catch (java.lang.OutOfMemoryError e) {
+            // Many of the renderscript filters allocated large (>16Mb resources) in order to apply.
+            System.gc();
+            displayLowMemoryToast();
+            Log.e(LOGTAG, "not enough memory for filter " + getName(), e);
         }
         return bitmap;
     }