OSDN Git Service

Fix crash / jank / presets add
authornicolasroard <nicolasroard@google.com>
Sat, 21 Sep 2013 01:49:41 +0000 (18:49 -0700)
committernicolasroard <nicolasroard@google.com>
Sat, 21 Sep 2013 01:51:47 +0000 (18:51 -0700)
- don't cache immutable bitmaps
- fix junk in anims/zoom/constrain
- fix edge glow when moving
- fix double-tap zoom
- fix presets / user presets adds
- fix state panel names for geometry ops

bug:10803026
Change-Id: I9328d7005d3ecee3566c104c3392de9325c50b74

src/com/android/gallery3d/filtershow/FilterShowActivity.java
src/com/android/gallery3d/filtershow/cache/BitmapCache.java
src/com/android/gallery3d/filtershow/filters/FilterCropRepresentation.java
src/com/android/gallery3d/filtershow/filters/FilterMirrorRepresentation.java
src/com/android/gallery3d/filtershow/filters/FilterRotateRepresentation.java
src/com/android/gallery3d/filtershow/filters/FilterStraightenRepresentation.java
src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java

index f055a6f..9d5005e 100644 (file)
@@ -94,6 +94,7 @@ import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation;
 import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation;
 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
 import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation;
+import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation;
 import com.android.gallery3d.filtershow.filters.FilterUserPresetRepresentation;
 import com.android.gallery3d.filtershow.filters.FiltersManager;
 import com.android.gallery3d.filtershow.filters.ImageFilter;
index 918ba89..cd63d30 100644 (file)
@@ -137,6 +137,10 @@ public class BitmapCache {
         if (DEBUG) {
             untrack(bitmap);
         }
+        if (!bitmap.isMutable()) {
+            Log.e(LOGTAG, "Trying to cache a non mutable bitmap");
+            return true;
+        }
         Long key = calcKey(bitmap.getWidth(), bitmap.getHeight());
         ArrayList<WeakReference<Bitmap>> list = mBitmapCache.get(key);
         if (list == null) {
index ec4b573..ba697d8 100644 (file)
@@ -35,7 +35,7 @@ public class FilterCropRepresentation extends FilterRepresentation {
     RectF mCrop = getNil();
 
     public FilterCropRepresentation(RectF crop) {
-        super(FilterCropRepresentation.class.getSimpleName());
+        super(SERIALIZATION_NAME);
         setSerializationName(SERIALIZATION_NAME);
         setShowParameterValue(true);
         setFilterClass(FilterCropRepresentation.class);
@@ -48,6 +48,7 @@ public class FilterCropRepresentation extends FilterRepresentation {
 
     public FilterCropRepresentation(FilterCropRepresentation m) {
         this(m.mCrop);
+        setName(m.getName());
     }
 
     public FilterCropRepresentation() {
index 84caa9e..c281443 100644 (file)
@@ -66,7 +66,7 @@ public class FilterMirrorRepresentation extends FilterRepresentation {
     }
 
     public FilterMirrorRepresentation(Mirror mirror) {
-        super(FilterMirrorRepresentation.class.getSimpleName());
+        super(SERIALIZATION_NAME);
         setSerializationName(SERIALIZATION_NAME);
         setShowParameterValue(false);
         setFilterClass(FilterMirrorRepresentation.class);
@@ -79,6 +79,7 @@ public class FilterMirrorRepresentation extends FilterRepresentation {
 
     public FilterMirrorRepresentation(FilterMirrorRepresentation m) {
         this(m.getMirror());
+        setName(m.getName());
     }
 
     public FilterMirrorRepresentation() {
index d7e0b58..4299dd3 100644 (file)
@@ -62,7 +62,7 @@ public class FilterRotateRepresentation extends FilterRepresentation {
     }
 
     public FilterRotateRepresentation(Rotation rotation) {
-        super(FilterRotateRepresentation.class.getSimpleName());
+        super(SERIALIZATION_NAME);
         setSerializationName(SERIALIZATION_NAME);
         setShowParameterValue(false);
         setFilterClass(FilterRotateRepresentation.class);
@@ -75,6 +75,7 @@ public class FilterRotateRepresentation extends FilterRepresentation {
 
     public FilterRotateRepresentation(FilterRotateRepresentation r) {
         this(r.getRotation());
+        setName(r.getName());
     }
 
     public FilterRotateRepresentation() {
index 4769b36..1ba80e8 100644 (file)
@@ -35,7 +35,7 @@ public class FilterStraightenRepresentation extends FilterRepresentation {
     float mStraighten;
 
     public FilterStraightenRepresentation(float straighten) {
-        super(FilterStraightenRepresentation.class.getSimpleName());
+        super(SERIALIZATION_NAME);
         setSerializationName(SERIALIZATION_NAME);
         setShowParameterValue(true);
         setFilterClass(FilterStraightenRepresentation.class);
@@ -48,6 +48,7 @@ public class FilterStraightenRepresentation extends FilterRepresentation {
 
     public FilterStraightenRepresentation(FilterStraightenRepresentation s) {
         this(s.getStraighten());
+        setName(s.getName());
     }
 
     public FilterStraightenRepresentation() {
index d890353..73068f8 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.gallery3d.filtershow.imageshow;
 
+import android.animation.Animator;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -32,7 +34,6 @@ import android.graphics.Shader;
 import android.graphics.drawable.NinePatchDrawable;
 import android.support.v4.widget.EdgeEffectCompat;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.GestureDetector;
 import android.view.GestureDetector.OnDoubleTapListener;
 import android.view.GestureDetector.OnGestureListener;
@@ -102,6 +103,12 @@ public class ImageShow extends View implements OnGestureListener,
     private int mCurrentEdgeEffect = 0;
     private int mEdgeSize = 100;
 
+    private static final int mAnimationSnapDelay = 200;
+    private static final int mAnimationZoomDelay = 400;
+    private ValueAnimator mAnimatorScale = null;
+    private ValueAnimator mAnimatorTranslateX = null;
+    private ValueAnimator mAnimatorTranslateY = null;
+
     private enum InteractionMode {
         NONE,
         SCALE,
@@ -346,13 +353,13 @@ public class ImageShow extends View implements OnGestureListener,
         if (image == null) {
             return;
         }
-        Matrix m = MasterImage.getImage().computeImageToScreen(image, 0, false);
+        MasterImage master = MasterImage.getImage();
+        Matrix m = master.computeImageToScreen(image, 0, false);
         if (m == null) {
             return;
         }
 
         canvas.save();
-        MasterImage master = MasterImage.getImage();
 
         RectF d = new RectF(0, 0, image.getWidth(), image.getHeight());
         m.mapRect(d);
@@ -365,7 +372,7 @@ public class ImageShow extends View implements OnGestureListener,
 
             // Animation uses the image before the change
             Bitmap previousImage = master.getPreviousImage();
-            Matrix mp = MasterImage.getImage().computeImageToScreen(previousImage, 0, false);
+            Matrix mp = master.computeImageToScreen(previousImage, 0, false);
             RectF dp = new RectF(0, 0, previousImage.getWidth(), previousImage.getHeight());
             mp.mapRect(dp);
             Rect previousBounds = new Rect();
@@ -498,7 +505,8 @@ public class ImageShow extends View implements OnGestureListener,
     }
 
     public void drawCompareImage(Canvas canvas, Bitmap image) {
-        boolean showsOriginal = MasterImage.getImage().showsOriginal();
+        MasterImage master = MasterImage.getImage();
+        boolean showsOriginal = master.showsOriginal();
         if (!showsOriginal && !mTouchShowOriginal)
             return;
         canvas.save();
@@ -538,7 +546,7 @@ public class ImageShow extends View implements OnGestureListener,
                 }
             }
             canvas.clipRect(d);
-            Matrix m = MasterImage.getImage().computeImageToScreen(image, 0, false);
+            Matrix m = master.computeImageToScreen(image, 0, false);
             canvas.drawBitmap(image, m, mPaint);
             Paint paint = new Paint();
             paint.setColor(Color.BLACK);
@@ -666,6 +674,57 @@ public class ImageShow extends View implements OnGestureListener,
         return true;
     }
 
+    private void startAnimTranslation(int fromX, int toX,
+                                      int fromY, int toY, int delay) {
+        if (fromX == toX && fromY == toY) {
+            return;
+        }
+        if (mAnimatorTranslateX != null) {
+            mAnimatorTranslateX.cancel();
+        }
+        if (mAnimatorTranslateY != null) {
+            mAnimatorTranslateY.cancel();
+        }
+        mAnimatorTranslateX = ValueAnimator.ofInt(fromX, toX);
+        mAnimatorTranslateY = ValueAnimator.ofInt(fromY, toY);
+        mAnimatorTranslateX.setDuration(delay);
+        mAnimatorTranslateY.setDuration(delay);
+        mAnimatorTranslateX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                Point translation = MasterImage.getImage().getTranslation();
+                translation.x = (Integer) animation.getAnimatedValue();
+                MasterImage.getImage().setTranslation(translation);
+                invalidate();
+            }
+        });
+        mAnimatorTranslateY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                Point translation = MasterImage.getImage().getTranslation();
+                translation.y = (Integer) animation.getAnimatedValue();
+                MasterImage.getImage().setTranslation(translation);
+                invalidate();
+            }
+        });
+        mAnimatorTranslateX.start();
+        mAnimatorTranslateY.start();
+    }
+
+    private void applyTranslationConstraints() {
+        float scaleFactor = MasterImage.getImage().getScaleFactor();
+        Point translation = MasterImage.getImage().getTranslation();
+        int x = translation.x;
+        int y = translation.y;
+        constrainTranslation(translation, scaleFactor);
+
+        if (x != translation.x || y != translation.y) {
+            startAnimTranslation(x, translation.x,
+                                 y, translation.y,
+                                 mAnimationSnapDelay);
+        }
+    }
+
     protected boolean enableComparison() {
         return true;
     }
@@ -674,19 +733,67 @@ public class ImageShow extends View implements OnGestureListener,
     public boolean onDoubleTap(MotionEvent arg0) {
         mZoomIn = !mZoomIn;
         float scale = 1.0f;
+        final float x = arg0.getX();
+        final float y = arg0.getY();
         if (mZoomIn) {
             scale = MasterImage.getImage().getMaxScaleFactor();
         }
         if (scale != MasterImage.getImage().getScaleFactor()) {
-            MasterImage.getImage().setScaleFactor(scale);
-            float translateX = (getWidth() / 2 - arg0.getX());
-            float translateY = (getHeight() / 2 - arg0.getY());
+            if (mAnimatorScale != null) {
+                mAnimatorScale.cancel();
+            }
+            mAnimatorScale = ValueAnimator.ofFloat(
+                    MasterImage.getImage().getScaleFactor(),
+                    scale
+            );
+            float translateX = (getWidth() / 2 - x);
+            float translateY = (getHeight() / 2 - y);
             Point translation = MasterImage.getImage().getTranslation();
-            translation.x = (int) (mOriginalTranslation.x + translateX);
-            translation.y = (int) (mOriginalTranslation.y + translateY);
+            int startTranslateX = translation.x;
+            int startTranslateY = translation.y;
+            if (scale != 1.0f) {
+                translation.x = (int) (mOriginalTranslation.x + translateX);
+                translation.y = (int) (mOriginalTranslation.y + translateY);
+            } else {
+                translation.x = 0;
+                translation.y = 0;
+            }
             constrainTranslation(translation, scale);
-            MasterImage.getImage().setTranslation(translation);
-            invalidate();
+
+            startAnimTranslation(startTranslateX, translation.x,
+                                 startTranslateY, translation.y,
+                                 mAnimationZoomDelay);
+            mAnimatorScale.setDuration(mAnimationZoomDelay);
+            mAnimatorScale.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    MasterImage.getImage().setScaleFactor((Float) animation.getAnimatedValue());
+                    invalidate();
+                }
+            });
+            mAnimatorScale.addListener(new Animator.AnimatorListener() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    applyTranslationConstraints();
+                    MasterImage.getImage().needsUpdatePartialPreview();
+                    invalidate();
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+
+                }
+
+                @Override
+                public void onAnimationRepeat(Animator animation) {
+
+                }
+            });
+            mAnimatorScale.start();
         }
         return true;
     }
@@ -695,6 +802,7 @@ public class ImageShow extends View implements OnGestureListener,
         int currentEdgeEffect = 0;
         if (scale <= 1) {
             mCurrentEdgeEffect = 0;
+            mEdgeEffect.finish();
             return;
         }
 
@@ -743,11 +851,11 @@ public class ImageShow extends View implements OnGestureListener,
         if (mCurrentEdgeEffect != currentEdgeEffect) {
             if (mCurrentEdgeEffect == 0 || currentEdgeEffect != 0) {
                 mCurrentEdgeEffect = currentEdgeEffect;
+                mEdgeEffect.finish();
             }
-            mEdgeEffect.finish();
             mEdgeEffect.setSize(getWidth(), mEdgeSize);
-            mEdgeEffect.onPull(mEdgeSize);
-        } else {
+        }
+        if (currentEdgeEffect != 0) {
             mEdgeEffect.onPull(mEdgeSize);
         }
     }
@@ -812,8 +920,8 @@ public class ImageShow extends View implements OnGestureListener,
         if (scaleFactor > MasterImage.getImage().getMaxScaleFactor()) {
             scaleFactor = MasterImage.getImage().getMaxScaleFactor();
         }
-        if (scaleFactor < 0.5) {
-            scaleFactor = 0.5f;
+        if (scaleFactor < 1.0f) {
+            scaleFactor = 1.0f;
         }
         MasterImage.getImage().setScaleFactor(scaleFactor);
         scaleFactor = img.getScaleFactor();
index bc4ce0c..7b8f1b3 100644 (file)
@@ -351,17 +351,13 @@ public class ImagePreset {
                 && preset.contains(FilterRepresentation.TYPE_FX)) {
                 FilterRepresentation rep = preset.getFilterRepresentationForType(
                         FilterRepresentation.TYPE_FX);
-                removeFilter(rep);
-                if (!isNoneBorderFilter(rep)) {
-                    mFilters.add(rep);
-                }
+                addFilter(rep);
             } else {
                 // user preset replaces everything
                 mFilters.clear();
                 for (int i = 0; i < preset.nbFilters(); i++) {
                     addFilter(preset.getFilterRepresentation(i));
                 }
-                mFilters.add(representation);
             }
         } else if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) {
             // Add geometry filter, removing duplicates and do-nothing operations.
@@ -386,52 +382,20 @@ public class ImagePreset {
                 mFilters.add(representation);
             }
         } else if (representation.getFilterType() == FilterRepresentation.TYPE_FX) {
-            boolean found = false;
+            boolean replaced = false;
             for (int i = 0; i < mFilters.size(); i++) {
                 FilterRepresentation current = mFilters.elementAt(i);
-                int type = current.getFilterType();
-                if (found) {
-                    if (type != FilterRepresentation.TYPE_VIGNETTE) {
-                        mFilters.remove(i);
-                        continue;
-                    }
-                }
-                if (type == FilterRepresentation.TYPE_FX) {
-                    if (current instanceof FilterUserPresetRepresentation) {
-                        ImagePreset preset = ((FilterUserPresetRepresentation) current)
-                                .getImagePreset();
-                        // If we had an existing user preset, let's remove all the presets that
-                        // were added by it
-                        for (int j = 0; j < preset.nbFilters(); j++) {
-                            FilterRepresentation rep = preset.getFilterRepresentation(j);
-                            int pos = getPositionForRepresentation(rep);
-                            if (pos != -1) {
-                                mFilters.remove(pos);
-                            }
-                        }
-                        int pos = getPositionForRepresentation(current);
-                        if (pos != -1) {
-                            mFilters.remove(pos);
-                        } else {
-                            pos = 0;
-                        }
-                        if (!isNoneFxFilter(representation)) {
-                            mFilters.add(pos, representation);
-                        }
-
-                    } else {
-                        mFilters.remove(i);
-                        if (!isNoneFxFilter(representation)) {
-                            mFilters.add(i, representation);
-                        }
+                if (current.getFilterType() == FilterRepresentation.TYPE_FX) {
+                    mFilters.remove(i);
+                    replaced = true;
+                    if (!isNoneBorderFilter(representation)) {
+                        mFilters.add(i, representation);
                     }
-                    found = true;
+                    break;
                 }
             }
-            if (!found) {
-                if (!isNoneFxFilter(representation)) {
-                    mFilters.add(representation);
-                }
+            if (!replaced) {
+                mFilters.add(0, representation);
             }
         } else {
             mFilters.add(representation);