OSDN Git Service

Pipeline refactoring
authornicolasroard <nicolasroard@google.com>
Tue, 2 Jul 2013 18:00:01 +0000 (11:00 -0700)
committernicolasroard <nicolasroard@google.com>
Tue, 2 Jul 2013 19:42:21 +0000 (12:42 -0700)
Remove the temp representations and instead use a triple
buffer for ImagePresets.

Change-Id: I4cdcfbe4941af72b38fe42385085ff4a20eb78cc

src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java
src/com/android/gallery3d/filtershow/filters/FilterRepresentation.java
src/com/android/gallery3d/filtershow/imageshow/MasterImage.java
src/com/android/gallery3d/filtershow/pipeline/Buffer.java
src/com/android/gallery3d/filtershow/pipeline/SharedBuffer.java
src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java [new file with mode: 0644]
src/com/android/gallery3d/filtershow/presets/ImagePreset.java

index 9901e57..dfba3f7 100644 (file)
@@ -359,16 +359,13 @@ public class CachingPipeline implements PipelineInterface {
             mFiltersManager.freeFilterResources(preset);
 
             Bitmap resizedOriginalBitmap = mResizedOriginalBitmap;
-            if (updateOriginalAllocation(preset)) {
+            if (updateOriginalAllocation(preset) || buffer.getProducer() == null) {
                 resizedOriginalBitmap = mResizedOriginalBitmap;
-                mEnvironment.cache(buffer.getProducer());
                 buffer.setProducer(resizedOriginalBitmap);
+                mEnvironment.cache(buffer.getProducer());
             }
 
-            Bitmap bitmap = null;
-            if (buffer.getProducer() != null) {
-                bitmap = buffer.getProducer().getBitmap();
-            }
+            Bitmap bitmap = buffer.getProducer().getBitmap();
             long time2 = System.currentTimeMillis();
 
             if (bitmap == null || (bitmap.getWidth() != resizedOriginalBitmap.getWidth())
index cac7e05..7d8481f 100644 (file)
@@ -27,6 +27,7 @@ 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.pipeline.SharedBuffer;
+import com.android.gallery3d.filtershow.pipeline.SharedPreset;
 import com.android.gallery3d.filtershow.presets.ImagePreset;
 
 public class FilteringPipeline implements Handler.Callback {
@@ -72,8 +73,6 @@ public class FilteringPipeline implements Handler.Callback {
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case NEW_PRESET: {
-                    SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer();
-                    buffer.swapConsumer();
                     MasterImage.getImage().notifyObservers();
                     if (mHasUnhandledPreviewRequest) {
                         updatePreviewBuffer();
@@ -96,12 +95,18 @@ public class FilteringPipeline implements Handler.Callback {
         }
         switch (msg.what) {
             case COMPUTE_PRESET: {
-                ImagePreset preset = (ImagePreset) msg.obj;
                 SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer();
-                mPreviewPipeline.compute(buffer, preset, COMPUTE_PRESET);
-                buffer.swapProducer();
-                Message uimsg = mUIHandler.obtainMessage(NEW_PRESET);
-                mUIHandler.sendMessage(uimsg);
+                SharedPreset preset = MasterImage.getImage().getPreviewPreset();
+                ImagePreset renderingPreset = preset.dequeuePreset();
+                if (renderingPreset != null) {
+                    mPreviewPipeline.compute(buffer, renderingPreset, COMPUTE_PRESET);
+                    // set the preset we used in the buffer for later inspection UI-side
+                    buffer.getProducer().setPreset(renderingPreset);
+                    buffer.getProducer().sync();
+                    buffer.swapProducer(); // push back the result
+                    Message uimsg = mUIHandler.obtainMessage(NEW_PRESET);
+                    mUIHandler.sendMessage(uimsg);
+                }
                 break;
             }
             case COMPUTE_RENDERING_REQUEST:
index a60410d..e6018bb 100644 (file)
@@ -47,8 +47,6 @@ public class FilterRepresentation implements Cloneable {
     public static final byte TYPE_TINYPLANET = 6;
     protected static final String NAME_TAG = "Name";
 
-    private FilterRepresentation mTempRepresentation = null;
-
     public FilterRepresentation(String name) {
         mName = name;
     }
@@ -67,8 +65,6 @@ public class FilterRepresentation implements Cloneable {
         representation.setShowParameterValue(showParameterValue());
         representation.mSerializationName = mSerializationName;
 
-        representation.mTempRepresentation =
-                mTempRepresentation != null ? mTempRepresentation.clone() : null;
         if (DEBUG) {
             Log.v(LOGTAG, "cloning from <" + this + "> to <" + representation + ">");
         }
@@ -140,28 +136,6 @@ public class FilterRepresentation implements Cloneable {
     public void useParametersFrom(FilterRepresentation a) {
     }
 
-    public void clearTempRepresentation() {
-        mTempRepresentation = null;
-    }
-
-    public synchronized void updateTempParametersFrom(FilterRepresentation representation) {
-        if (mTempRepresentation == null) {
-            try {
-                mTempRepresentation = representation.clone();
-            } catch (CloneNotSupportedException e) {
-                e.printStackTrace();
-            }
-        } else {
-            mTempRepresentation.useParametersFrom(representation);
-        }
-    }
-
-    public synchronized void synchronizeRepresentation() {
-        if (mTempRepresentation != null) {
-            useParametersFrom(mTempRepresentation);
-        }
-    }
-
     public boolean allowsSingleInstanceOnly() {
         return false;
     }
index 7667075..bc20888 100644 (file)
@@ -35,6 +35,7 @@ import com.android.gallery3d.filtershow.filters.FilterRepresentation;
 import com.android.gallery3d.filtershow.filters.ImageFilter;
 import com.android.gallery3d.filtershow.pipeline.Buffer;
 import com.android.gallery3d.filtershow.pipeline.SharedBuffer;
+import com.android.gallery3d.filtershow.pipeline.SharedPreset;
 import com.android.gallery3d.filtershow.presets.ImagePreset;
 import com.android.gallery3d.filtershow.state.StateAdapter;
 
@@ -58,6 +59,7 @@ public class MasterImage implements RenderingRequestCaller {
     private ImagePreset mFiltersOnlyPreset = null;
 
     private SharedBuffer mPreviewBuffer = new SharedBuffer();
+    private SharedPreset mPreviewPreset = new SharedPreset();
 
     private Bitmap mGeometryOnlyBitmap = null;
     private Bitmap mFiltersOnlyBitmap = null;
@@ -255,6 +257,10 @@ public class MasterImage implements RenderingRequestCaller {
         return mPreviewBuffer;
     }
 
+    public SharedPreset getPreviewPreset() {
+        return mPreviewPreset;
+    }
+
     public void setOriginalGeometry(Bitmap originalBitmapLarge) {
         GeometryMetadata geo = getPreset().getGeometry();
         float w = originalBitmapLarge.getWidth();
@@ -266,6 +272,7 @@ public class MasterImage implements RenderingRequestCaller {
     }
 
     public Bitmap getFilteredImage() {
+        mPreviewBuffer.swapConsumerIfNeeded(); // get latest bitmap
         Buffer consumer = mPreviewBuffer.getConsumer();
         if (consumer != null) {
             return consumer.getBitmap();
@@ -349,6 +356,7 @@ public class MasterImage implements RenderingRequestCaller {
     }
 
     public void invalidatePreview() {
+        mPreviewPreset.enqueuePreset(mPreset);
         mPreviewBuffer.invalidate();
         invalidatePartialPreview();
         invalidateHighresPreview();
@@ -554,4 +562,5 @@ public class MasterImage implements RenderingRequestCaller {
     public ImagePreset getLoadedPreset() {
         return mLoadedPreset;
     }
+
 }
index 7268516..c6dbdb7 100644 (file)
@@ -20,16 +20,21 @@ import android.graphics.Bitmap;
 import android.support.v8.renderscript.Allocation;
 import android.support.v8.renderscript.RenderScript;
 import com.android.gallery3d.filtershow.cache.CachingPipeline;
+import com.android.gallery3d.filtershow.presets.ImagePreset;
 
 public class Buffer {
+    private static final String LOGTAG = "Buffer";
     private Bitmap mBitmap;
     private Allocation mAllocation;
     private boolean mUseAllocation = false;
     private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
+    private ImagePreset mPreset;
 
     public Buffer(Bitmap bitmap) {
         RenderScript rs = CachingPipeline.getRenderScriptContext();
-        mBitmap = bitmap.copy(BITMAP_CONFIG, true);
+        if (bitmap != null) {
+            mBitmap = bitmap.copy(BITMAP_CONFIG, true);
+        }
         if (mUseAllocation) {
             // TODO: recreate the allocation when the RS context changes
             mAllocation = Allocation.createFromBitmap(rs, mBitmap,
@@ -38,6 +43,10 @@ public class Buffer {
         }
     }
 
+    public void setBitmap(Bitmap bitmap) {
+        mBitmap = bitmap.copy(BITMAP_CONFIG, true);
+    }
+
     public Bitmap getBitmap() {
         return mBitmap;
     }
@@ -52,5 +61,16 @@ public class Buffer {
         }
     }
 
+    public ImagePreset getPreset() {
+        return mPreset;
+    }
+
+    public void setPreset(ImagePreset preset) {
+        if ((mPreset == null) || (!mPreset.same(preset))) {
+            mPreset = new ImagePreset(preset);
+        } else {
+            mPreset.updateWith(preset);
+        }
+    }
 }
 
index 5871746..98e69f6 100644 (file)
@@ -17,7 +17,6 @@
 package com.android.gallery3d.filtershow.pipeline;
 
 import android.graphics.Bitmap;
-import android.util.Log;
 
 public class SharedBuffer {
 
@@ -26,15 +25,15 @@ public class SharedBuffer {
     private volatile Buffer mProducer = null;
     private volatile Buffer mConsumer = null;
     private volatile Buffer mIntermediate = null;
-    private volatile boolean mNeedsSwap = false;
 
+    private volatile boolean mNeedsSwap = false;
     private volatile boolean mNeedsRepaint = true;
 
-    public SharedBuffer() {
-    }
-
-    public synchronized void setProducer(Bitmap producer) {
-        mProducer = new Buffer(producer);
+    public void setProducer(Bitmap producer) {
+        Buffer buffer = new Buffer(producer);
+        synchronized (this) {
+            mProducer = buffer;
+        }
     }
 
     public synchronized Buffer getProducer() {
@@ -46,22 +45,16 @@ public class SharedBuffer {
     }
 
     public synchronized void swapProducer() {
-        if (mProducer != null) {
-            mProducer.sync();
-        }
         Buffer intermediate = mIntermediate;
         mIntermediate = mProducer;
         mProducer = intermediate;
         mNeedsSwap = true;
     }
 
-    public synchronized void swapConsumer() {
+    public synchronized void swapConsumerIfNeeded() {
         if (!mNeedsSwap) {
             return;
         }
-        if (mConsumer != null) {
-            mConsumer.sync();
-        }
         Buffer intermediate = mIntermediate;
         mIntermediate = mConsumer;
         mConsumer = intermediate;
diff --git a/src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java b/src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java
new file mode 100644 (file)
index 0000000..e874694
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2013 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.pipeline;
+
+import com.android.gallery3d.filtershow.presets.ImagePreset;
+
+public class SharedPreset {
+
+    private volatile ImagePreset mProducerPreset = null;
+    private volatile ImagePreset mConsumerPreset = null;
+    private volatile ImagePreset mIntermediatePreset = null;
+
+    public synchronized void enqueuePreset(ImagePreset preset) {
+        if (mProducerPreset == null || (!mProducerPreset.same(preset))) {
+            mProducerPreset = new ImagePreset(preset);
+        } else {
+            mProducerPreset.updateWith(preset);
+        }
+        ImagePreset temp = mIntermediatePreset;
+        mIntermediatePreset = mProducerPreset;
+        mProducerPreset = temp;
+    }
+
+    public synchronized ImagePreset dequeuePreset() {
+        ImagePreset temp = mConsumerPreset;
+        mConsumerPreset = mIntermediatePreset;
+        mIntermediatePreset = temp;
+        return mConsumerPreset;
+    }
+}
index 4ec39f7..d36bafd 100644 (file)
@@ -147,17 +147,15 @@ public class ImagePreset {
         if (representation == null) {
             return;
         }
-        synchronized (mFilters) {
-            if (representation instanceof GeometryMetadata) {
-                setGeometry((GeometryMetadata) representation);
-            } else {
-                int position = getPositionForRepresentation(representation);
-                if (position == -1) {
-                    return;
-                }
-                FilterRepresentation old = mFilters.elementAt(position);
-                old.updateTempParametersFrom(representation);
+        if (representation instanceof GeometryMetadata) {
+            setGeometry((GeometryMetadata) representation);
+        } else {
+            int position = getPositionForRepresentation(representation);
+            if (position == -1) {
+                return;
             }
+            FilterRepresentation old = mFilters.elementAt(position);
+            old.useParametersFrom(representation);
         }
         MasterImage.getImage().invalidatePreview();
         fillImageStateAdapter(MasterImage.getImage().getState());
@@ -175,7 +173,7 @@ public class ImagePreset {
         return mDoApplyFilters;
     }
 
-    public synchronized GeometryMetadata getGeometry() {
+    public GeometryMetadata getGeometry() {
         for (FilterRepresentation representation : mFilters) {
             if (representation instanceof GeometryMetadata) {
                 return (GeometryMetadata) representation;
@@ -223,7 +221,7 @@ public class ImagePreset {
         return true;
     }
 
-    public synchronized void setGeometry(GeometryMetadata representation) {
+    public void setGeometry(GeometryMetadata representation) {
         GeometryMetadata geoData = getGeometry();
         if (geoData != representation) {
             geoData.set(representation);
@@ -425,7 +423,6 @@ public class ImagePreset {
         // Returns a new bitmap.
         if (mDoApplyGeometry) {
             GeometryMetadata geoData = getGeometry();
-            geoData.synchronizeRepresentation();
             bitmap = environment.applyRepresentation(geoData, bitmap);
         }
         return bitmap;
@@ -436,7 +433,6 @@ public class ImagePreset {
         FilterRepresentation border = getFilterRepresentationForType(
                 FilterRepresentation.TYPE_BORDER);
         if (border != null && mDoApplyGeometry) {
-            border.synchronizeRepresentation();
             bitmap = environment.applyRepresentation(border, bitmap);
             if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) {
                 UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR,
@@ -463,11 +459,7 @@ public class ImagePreset {
                         "SaveFilters", "Total", to - from + 1);
             }
             for (int i = from; i < to; i++) {
-                FilterRepresentation representation = null;
-                synchronized (mFilters) {
-                    representation = mFilters.elementAt(i);
-                    representation.synchronizeRepresentation();
-                }
+                FilterRepresentation representation = mFilters.elementAt(i);
                 if (representation instanceof GeometryMetadata) {
                     // skip the geometry as it's already applied.
                     continue;
@@ -496,7 +488,6 @@ public class ImagePreset {
         FilterRepresentation border = getFilterRepresentationForType(
                 FilterRepresentation.TYPE_BORDER);
         if (border != null && mDoApplyGeometry) {
-            border.synchronizeRepresentation();
             // TODO: should keep the bitmap around
             Allocation bitmapIn = in;
             if (copyOut) {
@@ -518,11 +509,7 @@ public class ImagePreset {
                 to = mFilters.size();
             }
             for (int i = from; i < to; i++) {
-                FilterRepresentation representation = null;
-                synchronized (mFilters) {
-                    representation = mFilters.elementAt(i);
-                    representation.synchronizeRepresentation();
-                }
+                FilterRepresentation representation = mFilters.elementAt(i);
                 if (representation instanceof GeometryMetadata) {
                     // skip the geometry as it's already applied.
                     continue;
@@ -544,10 +531,7 @@ public class ImagePreset {
             return false;
         }
         for (int i = 0; i < mFilters.size(); i++) {
-            FilterRepresentation representation = null;
-            synchronized (mFilters) {
-                representation = mFilters.elementAt(i);
-            }
+            FilterRepresentation representation = mFilters.elementAt(i);
             if (representation instanceof GeometryMetadata
                 && ((GeometryMetadata) representation).hasModifications()) {
                 return false;
@@ -703,4 +687,16 @@ public class ImagePreset {
         FiltersManager filtersManager = FiltersManager.getManager();
         return filtersManager.createFilterFromName(name);
     }
+
+    public void updateWith(ImagePreset preset) {
+        if (preset.mFilters.size() != mFilters.size()) {
+            Log.e(LOGTAG, "Updating a preset with an incompatible one");
+            return;
+        }
+        for (int i = 0; i < mFilters.size(); i++) {
+            FilterRepresentation destRepresentation = mFilters.elementAt(i);
+            FilterRepresentation sourceRepresentation = preset.mFilters.elementAt(i);
+            destRepresentation.useParametersFrom(sourceRepresentation);
+        }
+    }
 }