summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/gallery3d/filtershow/cache/CachingPipeline.java11
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilter.java6
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java54
-rw-r--r--src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java12
-rw-r--r--src/com/android/gallery3d/filtershow/presets/ImagePreset.java23
5 files changed, 106 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
index 32d4ab094..b8dc466d9 100644
--- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
+++ b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
@@ -300,6 +300,17 @@ public class CachingPipeline {
}
}
+ public synchronized void renderImage(ImagePreset preset, Allocation in, Allocation out) {
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return;
+ }
+ setupEnvironment(preset, false);
+ mFiltersManager.freeFilterResources(preset);
+ preset.applyFilters(-1, -1, in, out, mEnvironment);
+ }
+ }
+
public synchronized Bitmap renderFinalImage(Bitmap bitmap, ImagePreset preset) {
synchronized (CachingPipeline.class) {
if (getRenderScriptContext() == null) {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
index 8cdec976b..96ab84f9d 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java
@@ -18,6 +18,7 @@ package com.android.gallery3d.filtershow.filters;
import android.graphics.Bitmap;
import android.graphics.Matrix;
+import android.support.v8.renderscript.Allocation;
import android.widget.Toast;
import com.android.gallery3d.filtershow.FilterShowActivity;
@@ -65,6 +66,11 @@ public abstract class ImageFilter implements Cloneable {
return mName;
}
+ public boolean supportsAllocationInput() { return false; }
+
+ public void apply(Allocation in, Allocation out) {
+ }
+
public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
// do nothing here, subclasses will implement filtering here
return bitmap;
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
index 013776878..0a45e83de 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
@@ -30,6 +30,8 @@ public abstract class ImageFilterRS extends ImageFilter {
private int mLastInputWidth = 0;
private int mLastInputHeight = 0;
+ public static boolean PERF_LOGGING = false;
+
private static ScriptC_grey mGreyConvert = null;
private static RenderScript mRScache = null;
@@ -38,6 +40,10 @@ public abstract class ImageFilterRS extends ImageFilter {
protected abstract void createFilter(android.content.res.Resources res,
float scaleFactor, int quality);
+ protected void createFilter(android.content.res.Resources res,
+ float scaleFactor, int quality, Allocation in) {}
+ protected void bindScriptValues(Allocation in) {}
+
protected abstract void runFilter();
protected void update(Bitmap bitmap) {
@@ -59,6 +65,38 @@ public abstract class ImageFilterRS extends ImageFilter {
}
@Override
+ public void apply(Allocation in, Allocation out) {
+ long startOverAll = System.nanoTime();
+ long startFilter = 0;
+ long endFilter = 0;
+ if (!mResourcesLoaded) {
+ CachingPipeline pipeline = getEnvironment().getCachingPipeline();
+ createFilter(pipeline.getResources(), getEnvironment().getScaleFactor(),
+ getEnvironment().getQuality(), in);
+ mResourcesLoaded = true;
+ }
+ startFilter = System.nanoTime();
+ bindScriptValues(in);
+ run(in, out);
+ if (PERF_LOGGING) {
+ getRenderScriptContext().finish();
+ endFilter = System.nanoTime();
+ long endOverAll = System.nanoTime();
+ String msg = String.format("%s; image size %dx%d; ", getName(),
+ in.getType().getX(), in.getType().getY());
+ long timeOverAll = (endOverAll - startOverAll) / 1000;
+ long timeFilter = (endFilter - startFilter) / 1000;
+ msg += String.format("over all %.2f ms (%.2f FPS); ",
+ timeOverAll / 1000.f, 1000000.f / timeOverAll);
+ msg += String.format("run filter %.2f ms (%.2f FPS)",
+ timeFilter / 1000.f, 1000000.f / timeFilter);
+ Log.i(LOGTAG, msg);
+ }
+ }
+
+ protected void run(Allocation in, Allocation out) {}
+
+ @Override
public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
return bitmap;
@@ -99,6 +137,7 @@ public abstract class ImageFilterRS extends ImageFilter {
displayLowMemoryToast();
Log.e(LOGTAG, "not enough memory for filter " + getName(), e);
}
+
return bitmap;
}
@@ -146,6 +185,21 @@ public abstract class ImageFilterRS extends ImageFilter {
return ret;
}
+ public Allocation loadScaledResourceAlpha(int resource, int w, int h, int inSampleSize) {
+ Resources res = CachingPipeline.getResources();
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inPreferredConfig = Bitmap.Config.ALPHA_8;
+ options.inSampleSize = inSampleSize;
+ Bitmap bitmap = BitmapFactory.decodeResource(
+ res,
+ resource, options);
+ Bitmap resizeBitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
+ Allocation ret = convertRGBAtoA(resizeBitmap);
+ resizeBitmap.recycle();
+ bitmap.recycle();
+ return ret;
+ }
+
public Allocation loadResourceAlpha(int resource) {
return loadScaledResourceAlpha(resource, 1);
}
diff --git a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java
index b474b8412..7b0e0193f 100644
--- a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java
+++ b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java
@@ -17,6 +17,7 @@
package com.android.gallery3d.filtershow.presets;
import android.graphics.Bitmap;
+import android.support.v8.renderscript.Allocation;
import com.android.gallery3d.filtershow.cache.CachingPipeline;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.filters.FiltersManager;
@@ -61,6 +62,17 @@ public class FilterEnvironment {
return mFiltersManager;
}
+ public void applyRepresentation(FilterRepresentation representation,
+ Allocation in, Allocation out) {
+ ImageFilter filter = mFiltersManager.getFilterForRepresentation(representation);
+ filter.useRepresentation(representation);
+ filter.setEnvironment(this);
+ if (filter.supportsAllocationInput()) {
+ filter.apply(in, out);
+ }
+ filter.setEnvironment(null);
+ }
+
public Bitmap applyRepresentation(FilterRepresentation representation, Bitmap bitmap) {
ImageFilter filter = mFiltersManager.getFilterForRepresentation(representation);
filter.useRepresentation(representation);
diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
index 2858ea6e5..791164f5c 100644
--- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java
@@ -18,6 +18,7 @@ package com.android.gallery3d.filtershow.presets;
import android.graphics.Bitmap;
import android.graphics.Rect;
+import android.support.v8.renderscript.Allocation;
import android.util.Log;
import com.android.gallery3d.filtershow.ImageStateAdapter;
@@ -473,6 +474,28 @@ public class ImagePreset {
return bitmap;
}
+ public void applyFilters(int from, int to, Allocation in, Allocation out, FilterEnvironment environment) {
+ if (mDoApplyFilters) {
+ if (from < 0) {
+ from = 0;
+ }
+ if (to == -1) {
+ to = mFilters.size();
+ }
+ for (int i = from; i < to; i++) {
+ FilterRepresentation representation = null;
+ synchronized (mFilters) {
+ representation = mFilters.elementAt(i);
+ representation.synchronizeRepresentation();
+ }
+ if (i > from) {
+ in.copyFrom(out);
+ }
+ environment.applyRepresentation(representation, in, out);
+ }
+ }
+ }
+
public boolean canDoPartialRendering() {
if (mGeoData.hasModifications()) {
return false;