From 91d26f6c3b183862eeffc1856e2d758e800d13f4 Mon Sep 17 00:00:00 2001 From: John Hoford Date: Thu, 18 Apr 2013 18:43:29 -0700 Subject: [PATCH] tiny planet fix bug:8323524 Change-Id: I39283face7079574dbe25e797323a84141930f9a --- jni/filters/tinyplanet.cc | 1 + .../gallery3d/filtershow/EditorPlaceHolder.java | 10 ++- .../gallery3d/filtershow/FilterShowActivity.java | 3 +- .../filtershow/cache/CachingPipeline.java | 14 ++-- .../filtershow/cache/TripleBufferBitmap.java | 8 +++ .../gallery3d/filtershow/editors/Editor.java | 1 + .../filtershow/editors/EditorTinyPlanet.java | 6 ++ .../filtershow/editors/ParametricEditor.java | 1 + .../filters/FilterTinyPlanetRepresentation.java | 9 +++ .../filtershow/filters/ImageFilterTinyPlanet.java | 46 ++++-------- .../filtershow/imageshow/ImageTinyPlanet.java | 81 ++++++++++++++++++++-- .../filtershow/presets/FilterEnvironment.java | 34 +++++++++ 12 files changed, 169 insertions(+), 45 deletions(-) diff --git a/jni/filters/tinyplanet.cc b/jni/filters/tinyplanet.cc index a40470d34..beac0861a 100644 --- a/jni/filters/tinyplanet.cc +++ b/jni/filters/tinyplanet.cc @@ -80,6 +80,7 @@ inline void InterpolatePixel(const ImageRGBA &image, float x, float y, ax * ay * p2[4] + axn * ay * p2[0] + 0.5f); p++; p2++; + dest[3] = 0xFF; } // Wrap circular coordinates around the globe diff --git a/src/com/android/gallery3d/filtershow/EditorPlaceHolder.java b/src/com/android/gallery3d/filtershow/EditorPlaceHolder.java index 735803c71..38424ec1f 100644 --- a/src/com/android/gallery3d/filtershow/EditorPlaceHolder.java +++ b/src/com/android/gallery3d/filtershow/EditorPlaceHolder.java @@ -1,6 +1,7 @@ package com.android.gallery3d.filtershow; import android.view.View; +import android.view.ViewParent; import android.widget.FrameLayout; import com.android.gallery3d.filtershow.cache.ImageLoader; @@ -49,7 +50,14 @@ public class EditorPlaceHolder { editor.setImageLoader(mImageLoader); mContainer.setVisibility(View.VISIBLE); mContainer.removeAllViews(); - mContainer.addView(editor.getTopLevelView()); + View eview = editor.getTopLevelView(); + ViewParent parent = eview.getParent(); + + if (parent != null && parent instanceof FrameLayout) { + ((FrameLayout) parent).removeAllViews(); + } + + mContainer.addView(eview); hideOldViews(); editor.setVisibility(View.VISIBLE); return editor; diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java index fb8984989..20061eea0 100644 --- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java +++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java @@ -482,7 +482,8 @@ public class FilterShowActivity extends FragmentActivity implements OnItemClickL if (mAction == CROP_ACTION) { mPanelController.showComponent(findViewById(EditorCrop.ID)); } else if (mAction == TINY_PLANET_ACTION) { - mPanelController.showComponent(findViewById(EditorTinyPlanet.ID)); + FilterIconButton button = (FilterIconButton) findViewById(EditorTinyPlanet.ID); + button.onClick(button); } super.onPostExecute(result); } diff --git a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java index 8cb8f8f9e..566d161b5 100644 --- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java +++ b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java @@ -22,9 +22,9 @@ import android.graphics.Bitmap; import android.support.v8.renderscript.Allocation; import android.support.v8.renderscript.RenderScript; import android.util.Log; + import com.android.gallery3d.filtershow.filters.FiltersManager; import com.android.gallery3d.filtershow.filters.ImageFilterGeometry; -import com.android.gallery3d.filtershow.filters.ImageFilterRS; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.presets.FilterEnvironment; @@ -357,19 +357,25 @@ public class CachingPipeline { Bitmap resizedOriginalBitmap = mResizedOriginalBitmap; if (updateOriginalAllocation(preset)) { resizedOriginalBitmap = mResizedOriginalBitmap; - buffer.updateBitmaps(resizedOriginalBitmap); + mEnvironment.cache(buffer.getProducer()); + buffer.updateProducerBitmap(resizedOriginalBitmap); } Bitmap bitmap = buffer.getProducer(); long time2 = System.currentTimeMillis(); if (bitmap == null || (bitmap.getWidth() != resizedOriginalBitmap.getWidth()) || (bitmap.getHeight() != resizedOriginalBitmap.getHeight())) { - buffer.updateBitmaps(resizedOriginalBitmap); + mEnvironment.cache(buffer.getProducer()); + buffer.updateProducerBitmap(resizedOriginalBitmap); bitmap = buffer.getProducer(); } mOriginalAllocation.copyTo(bitmap); - bitmap = preset.apply(bitmap, mEnvironment); + Bitmap tmpbitmap = preset.apply(bitmap, mEnvironment); + if (tmpbitmap != bitmap) { + mEnvironment.cache(buffer.getProducer()); + buffer.setProducer(tmpbitmap); + } mFiltersManager.freeFilterResources(preset); diff --git a/src/com/android/gallery3d/filtershow/cache/TripleBufferBitmap.java b/src/com/android/gallery3d/filtershow/cache/TripleBufferBitmap.java index d91d64df6..ba7b76925 100644 --- a/src/com/android/gallery3d/filtershow/cache/TripleBufferBitmap.java +++ b/src/com/android/gallery3d/filtershow/cache/TripleBufferBitmap.java @@ -44,6 +44,14 @@ public class TripleBufferBitmap { mIntermediate = mBitmaps[2]; } + public synchronized void updateProducerBitmap(Bitmap bitmap) { + mProducer = bitmap.copy(mBitmapConfig, true); + } + + public synchronized void setProducer(Bitmap producer) { + mProducer = producer; + } + public synchronized Bitmap getProducer() { return mProducer; } diff --git a/src/com/android/gallery3d/filtershow/editors/Editor.java b/src/com/android/gallery3d/filtershow/editors/Editor.java index 036745d3c..1e239e632 100644 --- a/src/com/android/gallery3d/filtershow/editors/Editor.java +++ b/src/com/android/gallery3d/filtershow/editors/Editor.java @@ -214,6 +214,7 @@ public class Editor implements OnSeekBarChangeListener, SwapButton.SwapButtonLis public void commitLocalRepresentation() { ImagePreset preset = MasterImage.getImage().getPreset(); preset.updateFilterRepresentation(getLocalRepresentation()); + mPanelController.onNewValue(-1); } /** diff --git a/src/com/android/gallery3d/filtershow/editors/EditorTinyPlanet.java b/src/com/android/gallery3d/filtershow/editors/EditorTinyPlanet.java index 4b005c459..9376fbef0 100644 --- a/src/com/android/gallery3d/filtershow/editors/EditorTinyPlanet.java +++ b/src/com/android/gallery3d/filtershow/editors/EditorTinyPlanet.java @@ -49,4 +49,10 @@ public class EditorTinyPlanet extends BasicEditor { mImageTinyPlanet.setRepresentation(drawRep); } } + + public void updateUI() { + if (mControl != null) { + mControl.updateUI(); + } + } } diff --git a/src/com/android/gallery3d/filtershow/editors/ParametricEditor.java b/src/com/android/gallery3d/filtershow/editors/ParametricEditor.java index 9c275d4f3..e49f6cd15 100644 --- a/src/com/android/gallery3d/filtershow/editors/ParametricEditor.java +++ b/src/com/android/gallery3d/filtershow/editors/ParametricEditor.java @@ -198,6 +198,7 @@ public class ParametricEditor extends Editor { public void commitLocalRepresentation() { super.commitLocalRepresentation(); FilterRepresentation rep = getLocalRepresentation(); + mPanelController.onNewValue(-1); } @Override diff --git a/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java index 7b69ce9e0..ac5e04601 100644 --- a/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java +++ b/src/com/android/gallery3d/filtershow/filters/FilterTinyPlanetRepresentation.java @@ -31,6 +31,7 @@ public class FilterTinyPlanetRepresentation extends FilterBasicRepresentation { setTextId(R.string.tinyplanet); setButtonId(R.id.tinyplanetButton); setEditorId(EditorTinyPlanet.ID); + setMinimum(1); } @Override @@ -42,6 +43,14 @@ public class FilterTinyPlanetRepresentation extends FilterBasicRepresentation { return representation; } + @Override + public void useParametersFrom(FilterRepresentation a) { + FilterTinyPlanetRepresentation representation = (FilterTinyPlanetRepresentation) a; + super.useParametersFrom(a); + mAngle = representation.mAngle; + setZoom(representation.getZoom()); + } + public void setAngle(float angle) { mAngle = angle; } diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java index 9874deaaf..37d5739a0 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java @@ -65,30 +65,34 @@ public class ImageFilterTinyPlanet extends SimpleImageFilter { return new FilterTinyPlanetRepresentation(); } + native protected void nativeApplyFilter( Bitmap bitmapIn, int width, int height, Bitmap bitmapOut, int outSize, float scale, float angle); + @Override public Bitmap apply(Bitmap bitmapIn, float scaleFactor, int quality) { int w = bitmapIn.getWidth(); int h = bitmapIn.getHeight(); int outputSize = (int) (w / 2f); ImagePreset preset = getImagePreset(); - + Bitmap mBitmapOut = null; if (preset != null) { XMPMeta xmp = preset.getImageLoader().getXmpObject(); // Do nothing, just use bitmapIn as is if we don't have XMP. if(xmp != null) { - bitmapIn = applyXmp(bitmapIn, xmp, w); + bitmapIn = applyXmp(bitmapIn, xmp, w); + } + } + if (mBitmapOut != null) { + if (outputSize != mBitmapOut.getHeight()) { + mBitmapOut = null; } } - - Bitmap mBitmapOut = null; while (mBitmapOut == null) { try { - mBitmapOut = Bitmap.createBitmap( - outputSize, outputSize, Bitmap.Config.ARGB_8888); + mBitmapOut = getEnvironment().getBitmap(outputSize, outputSize); } catch (java.lang.OutOfMemoryError e) { System.gc(); outputSize /= 2; @@ -98,32 +102,6 @@ public class ImageFilterTinyPlanet extends SimpleImageFilter { nativeApplyFilter(bitmapIn, bitmapIn.getWidth(), bitmapIn.getHeight(), mBitmapOut, outputSize, mParameters.getZoom() / 100f, mParameters.getAngle()); - if (true) { - // TODO(hoford): FIXME and remove this section - String text = "Tiny Planet Not Working"; - int w2 = bitmapIn.getWidth() / 2; - int h2 = bitmapIn.getHeight() / 2; - Canvas c = new Canvas(bitmapIn); - Paint p = new Paint(); - Rect src = new Rect(0, 0, mBitmapOut.getWidth(), mBitmapOut.getHeight()); - Rect dst = new Rect(0, 0, bitmapIn.getWidth(), bitmapIn.getHeight()); - c.drawBitmap(mBitmapOut, 0, 0, p); - float size = Math.min(w2, h2) / 4f; - p.setTextSize(size); - p.setColor(0xFF000000); - p.setStyle(Paint.Style.STROKE); - p.setStrokeWidth(20); - Rect bounds = new Rect(); - p.getTextBounds(text, 0, text.length(), bounds); - int tw = bounds.width() / 2; - c.drawText(text, w2 - tw, h2, p); - - p.setColor(0xFFFF0000); - p.setStyle(Paint.Style.FILL); - p.setStrokeWidth(0); - - c.drawText(text, w2 - tw, h2, p); - } return mBitmapOut; } @@ -150,8 +128,8 @@ public class ImageFilterTinyPlanet extends SimpleImageFilter { while (paddedBitmap == null) { try { paddedBitmap = Bitmap.createBitmap( - (int) (fullPanoWidth * scale), (int) (fullPanoHeight * scale), - Bitmap.Config.ARGB_8888); + (int) (fullPanoWidth * scale), (int) (fullPanoHeight * scale), + Bitmap.Config.ARGB_8888); } catch (java.lang.OutOfMemoryError e) { System.gc(); scale /= 2; diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java index a49636fae..25a0a9073 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java @@ -17,14 +17,20 @@ package com.android.gallery3d.filtershow.imageshow; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.RectF; import android.util.AttributeSet; import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.ScaleGestureDetector.OnScaleGestureListener; import com.android.gallery3d.filtershow.editors.BasicEditor; +import com.android.gallery3d.filtershow.editors.EditorTinyPlanet; import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation; public class ImageTinyPlanet extends ImageShow { + private static final String LOGTAG = "ImageTinyPlanet"; private float mTouchCenterX = 0; private float mTouchCenterY = 0; @@ -34,14 +40,48 @@ public class ImageTinyPlanet extends ImageShow { private float mCenterY = 0; private float mStartAngle = 0; private FilterTinyPlanetRepresentation mTinyPlanetRep; - private BasicEditor mEditorTinyPlanet; + private EditorTinyPlanet mEditorTinyPlanet; + private ScaleGestureDetector mScaleGestureDetector = null; + boolean mInScale = false; + RectF mDestRect = new RectF(); + + OnScaleGestureListener mScaleGestureListener = new OnScaleGestureListener() { + private float mScale = 100; + @Override + public void onScaleEnd(ScaleGestureDetector detector) { + mInScale = false; + } + + @Override + public boolean onScaleBegin(ScaleGestureDetector detector) { + mInScale = true; + mScale = mTinyPlanetRep.getValue(); + return true; + } + + @Override + public boolean onScale(ScaleGestureDetector detector) { + int value = mTinyPlanetRep.getValue(); + mScale *= detector.getScaleFactor(); + value = (int) (mScale); + value = Math.min(mTinyPlanetRep.getMaximum(), value); + value = Math.max(mTinyPlanetRep.getMinimum(), value); + mTinyPlanetRep.setValue(value); + invalidate(); + mEditorTinyPlanet.commitLocalRepresentation(); + mEditorTinyPlanet.updateUI(); + return true; + } + }; public ImageTinyPlanet(Context context) { super(context); + mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener); } public ImageTinyPlanet(Context context, AttributeSet attrs) { super(context, attrs); + mScaleGestureDetector = new ScaleGestureDetector(context,mScaleGestureListener ); } protected static float angleFor(float dx, float dy) { @@ -70,18 +110,21 @@ public class ImageTinyPlanet extends ImageShow { mCurrentY = y; mCenterX = getWidth() / 2; mCenterY = getHeight() / 2; + mScaleGestureDetector.onTouchEvent(event); + if (mInScale) { + return true; + } switch (event.getActionMasked()) { case (MotionEvent.ACTION_DOWN): mTouchCenterX = x; mTouchCenterY = y; mStartAngle = mTinyPlanetRep.getAngle(); break; - case (MotionEvent.ACTION_UP): + case (MotionEvent.ACTION_MOVE): mTinyPlanetRep.setAngle(mStartAngle + getCurrentTouchAngle()); break; } - resetImageCaches(this); invalidate(); mEditorTinyPlanet.commitLocalRepresentation(); return true; @@ -92,12 +135,40 @@ public class ImageTinyPlanet extends ImageShow { } public void setEditor(BasicEditor editorTinyPlanet) { - mEditorTinyPlanet = editorTinyPlanet; + mEditorTinyPlanet = (EditorTinyPlanet) editorTinyPlanet; } @Override public void onDraw(Canvas canvas) { - super.onDraw(canvas); + Bitmap bitmap = MasterImage.getImage().getHighresImage(); + if (bitmap == null) { + bitmap = MasterImage.getImage().getFilteredImage(); + } + + if (bitmap != null) { + display(canvas, bitmap); + } } + private void display(Canvas canvas, Bitmap bitmap) { + float sw = canvas.getWidth(); + float sh = canvas.getHeight(); + float iw = bitmap.getWidth(); + float ih = bitmap.getHeight(); + float nsw = sw; + float nsh = sh; + + if (sw * ih > sh * iw) { + nsw = sh * iw / ih; + } else { + nsh = sw * ih / iw; + } + + mDestRect.left = (sw - nsw) / 2; + mDestRect.top = (sh - nsh) / 2; + mDestRect.right = sw - mDestRect.left; + mDestRect.bottom = sh - mDestRect.top; + + canvas.drawBitmap(bitmap, null, mDestRect, mPaint); + } } diff --git a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java index 7b0e0193f..3c53227fc 100644 --- a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java +++ b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java @@ -18,17 +18,51 @@ package com.android.gallery3d.filtershow.presets; import android.graphics.Bitmap; import android.support.v8.renderscript.Allocation; +import android.util.Log; + import com.android.gallery3d.filtershow.cache.CachingPipeline; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.filters.FiltersManager; import com.android.gallery3d.filtershow.filters.ImageFilter; +import java.lang.ref.WeakReference; +import java.util.HashMap; + public class FilterEnvironment { + private static final String LOGTAG = "FilterEnvironment"; private ImagePreset mImagePreset; private float mScaleFactor; private int mQuality; private FiltersManager mFiltersManager; private CachingPipeline mCachingPipeline; + private HashMap> + bitmapCach = new HashMap>(); + + public void cache(Bitmap bitmap) { + if (bitmap == null) { + return; + } + Long key = calcKey(bitmap.getWidth(), bitmap.getHeight()); + bitmapCach.put(key, new WeakReference(bitmap)); + } + + public Bitmap getBitmap(int w, int h) { + Long key = calcKey(w, h); + WeakReference ref = bitmapCach.remove(key); + Bitmap bitmap = null; + if (ref != null) { + bitmap = ref.get(); + } + if (bitmap == null) { + bitmap = Bitmap.createBitmap( + w, h, Bitmap.Config.ARGB_8888); + } + return bitmap; + } + + private Long calcKey(long w, long h) { + return (w << 32) | (h << 32); + } public void setImagePreset(ImagePreset imagePreset) { mImagePreset = imagePreset; -- 2.11.0