OSDN Git Service

Add a direct rendering mode
authornicolasroard <nicolasroard@google.com>
Thu, 11 Apr 2013 02:27:57 +0000 (19:27 -0700)
committernicolasroard <nicolasroard@google.com>
Fri, 12 Apr 2013 18:55:51 +0000 (11:55 -0700)
This takes input and output allocations.
Also added a utility method in ImageFilterRS
to scale textures at screen resolution.

bug:8603245
bug:8588853

Change-Id: Ic5e4dea2289f0edd7518fc07f04b523be5316e82

src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
src/com/android/gallery3d/filtershow/filters/ImageFilter.java
src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java
src/com/android/gallery3d/filtershow/presets/ImagePreset.java

index 32d4ab0..b8dc466 100644 (file)
@@ -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) {
index 8cdec97..96ab84f 100644 (file)
@@ -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;
index 0137768..0a45e83 100644 (file)
@@ -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);
     }
index b474b84..7b0e019 100644 (file)
@@ -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);
index 2858ea6..791164f 100644 (file)
@@ -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;