summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolasroard <nicolasroard@google.com>2013-03-27 22:10:01 -0700
committernicolasroard <nicolasroard@google.com>2013-03-27 23:28:15 -0700
commit83facdef714b729aeab4d51919206d95a7afb165 (patch)
tree116257518dc9e6a359dc16baf8c7cfa7b76784c9
parent6d2104b2dd31e39e8f3c178375d4d91055a24a54 (diff)
downloadandroid_packages_apps_Snap-83facdef714b729aeab4d51919206d95a7afb165.tar.gz
android_packages_apps_Snap-83facdef714b729aeab4d51919206d95a7afb165.tar.bz2
android_packages_apps_Snap-83facdef714b729aeab4d51919206d95a7afb165.zip
Fix deadlock.
Move the RenderScript context and Resources to CachingPipeline. bug:8491107 Change-Id: I912555c87b060e4515cc1a4c66c8a8c9c840532d
-rw-r--r--src/com/android/gallery3d/filtershow/FilterShowActivity.java5
-rw-r--r--src/com/android/gallery3d/filtershow/cache/CachingPipeline.java276
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java92
3 files changed, 201 insertions, 172 deletions
diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
index 14a51392c..409f1e366 100644
--- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java
+++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java
@@ -50,6 +50,7 @@ import android.widget.Toast;
import com.android.gallery3d.R;
import com.android.gallery3d.data.LocalAlbum;
+import com.android.gallery3d.filtershow.cache.CachingPipeline;
import com.android.gallery3d.filtershow.cache.FilteringPipeline;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.editors.BasicEditor;
@@ -135,8 +136,8 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
clearGalleryBitmapPool();
+ CachingPipeline.createRenderscriptContext(this);
setupMasterImage();
- ImageFilterRS.createRenderscriptContext(this);
setDefaultValues();
fillEditors();
@@ -526,7 +527,7 @@ public class FilterShowActivity extends Activity implements OnItemClickListener,
FiltersManager.getPreviewManager().freeRSFilterScripts();
FiltersManager.getManager().freeRSFilterScripts();
FiltersManager.reset();
- ImageFilterRS.destroyRenderScriptContext();
+ CachingPipeline.destroyRenderScriptContext();
super.onDestroy();
}
diff --git a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
index f2b17fc0c..bc1d4505d 100644
--- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
+++ b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java
@@ -16,6 +16,8 @@
package com.android.gallery3d.filtershow.cache;
+import android.app.Activity;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.RenderScript;
@@ -33,6 +35,9 @@ public class CachingPipeline {
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
+ private static volatile RenderScript sRS = null;
+ private static volatile Resources sResources = null;
+
private FiltersManager mFiltersManager = null;
private volatile Bitmap mOriginalBitmap = null;
private volatile Bitmap mResizedOriginalBitmap = null;
@@ -56,24 +61,60 @@ public class CachingPipeline {
mName = name;
}
- public synchronized void reset() {
- mOriginalBitmap = null; // just a reference to the bitmap in ImageLoader
- if (mResizedOriginalBitmap != null) {
- mResizedOriginalBitmap.recycle();
- mResizedOriginalBitmap = null;
- }
- if (mOriginalAllocation != null) {
- mOriginalAllocation.destroy();
- mOriginalAllocation = null;
- }
- if (mFiltersOnlyOriginalAllocation != null) {
- mFiltersOnlyOriginalAllocation.destroy();
- mFiltersOnlyOriginalAllocation = null;
+ public static synchronized Resources getResources() {
+ return sResources;
+ }
+
+ public static synchronized void setResources(Resources resources) {
+ sResources = resources;
+ }
+
+ public static synchronized RenderScript getRenderScriptContext() {
+ return sRS;
+ }
+
+ public static synchronized void setRenderScriptContext(RenderScript RS) {
+ sRS = RS;
+ }
+
+ public static synchronized void createRenderscriptContext(Activity context) {
+ if (sRS != null) {
+ Log.w(LOGTAG, "A prior RS context exists when calling setRenderScriptContext");
+ destroyRenderScriptContext();
}
- mPreviousGeometry = null;
- mPreviewScaleFactor = 1.0f;
+ sRS = RenderScript.create(context);
+ sResources = context.getResources();
+ }
- destroyPixelAllocations();
+ public static synchronized void destroyRenderScriptContext() {
+ sRS.destroy();
+ sRS = null;
+ sResources = null;
+ }
+
+ public synchronized void reset() {
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return;
+ }
+ mOriginalBitmap = null; // just a reference to the bitmap in ImageLoader
+ if (mResizedOriginalBitmap != null) {
+ mResizedOriginalBitmap.recycle();
+ mResizedOriginalBitmap = null;
+ }
+ if (mOriginalAllocation != null) {
+ mOriginalAllocation.destroy();
+ mOriginalAllocation = null;
+ }
+ if (mFiltersOnlyOriginalAllocation != null) {
+ mFiltersOnlyOriginalAllocation.destroy();
+ mFiltersOnlyOriginalAllocation = null;
+ }
+ mPreviousGeometry = null;
+ mPreviewScaleFactor = 1.0f;
+
+ destroyPixelAllocations();
+ }
}
private synchronized void destroyPixelAllocations() {
@@ -143,7 +184,7 @@ public class CachingPipeline {
Log.v(LOGTAG, "geometry has changed");
}
- RenderScript RS = ImageFilterRS.getRenderScriptContext();
+ RenderScript RS = getRenderScriptContext();
Allocation filtersOnlyOriginalAllocation = mFiltersOnlyOriginalAllocation;
mFiltersOnlyOriginalAllocation = Allocation.createFromBitmap(RS, originalBitmap,
@@ -165,119 +206,138 @@ public class CachingPipeline {
}
public synchronized void render(RenderingRequest request) {
- if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
- && request.getBitmap() == null)
- || request.getImagePreset() == null) {
- return;
- }
-
- if (DEBUG) {
- Log.v(LOGTAG, "render image of type " + getType(request));
- }
-
- Bitmap bitmap = request.getBitmap();
- ImagePreset preset = request.getImagePreset();
- setupEnvironment(preset);
- mFiltersManager.freeFilterResources(preset);
-
- if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
- ImageLoader loader = MasterImage.getImage().getImageLoader();
- if (loader == null) {
- Log.w(LOGTAG, "loader not yet setup, cannot handle: " + getType(request));
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
return;
}
- bitmap = loader.getScaleOneImageForPreset(request.getBounds(),
- request.getDestination());
- if (bitmap == null) {
- Log.w(LOGTAG, "could not get bitmap for: " + getType(request));
+ if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
+ && request.getBitmap() == null)
+ || request.getImagePreset() == null) {
return;
}
- }
- if (request.getType() == RenderingRequest.FULL_RENDERING
- || request.getType() == RenderingRequest.GEOMETRY_RENDERING
- || request.getType() == RenderingRequest.FILTERS_RENDERING) {
- updateOriginalAllocation(preset);
- }
+ if (DEBUG) {
+ Log.v(LOGTAG, "render image of type " + getType(request));
+ }
- if (DEBUG) {
- Log.v(LOGTAG, "after update, req bitmap (" + bitmap.getWidth() + "x" + bitmap.getHeight()
- +" ? resizeOriginal (" + mResizedOriginalBitmap.getWidth() + "x"
- + mResizedOriginalBitmap.getHeight());
- }
+ Bitmap bitmap = request.getBitmap();
+ ImagePreset preset = request.getImagePreset();
+ setupEnvironment(preset);
+ mFiltersManager.freeFilterResources(preset);
- if (request.getType() == RenderingRequest.FULL_RENDERING
- || request.getType() == RenderingRequest.GEOMETRY_RENDERING) {
- mOriginalAllocation.copyTo(bitmap);
- } else if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
- mFiltersOnlyOriginalAllocation.copyTo(bitmap);
- }
+ if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ ImageLoader loader = MasterImage.getImage().getImageLoader();
+ if (loader == null) {
+ Log.w(LOGTAG, "loader not yet setup, cannot handle: " + getType(request));
+ return;
+ }
+ bitmap = loader.getScaleOneImageForPreset(request.getBounds(),
+ request.getDestination());
+ if (bitmap == null) {
+ Log.w(LOGTAG, "could not get bitmap for: " + getType(request));
+ return;
+ }
+ }
- if (request.getType() == RenderingRequest.FULL_RENDERING
- || request.getType() == RenderingRequest.FILTERS_RENDERING
- || request.getType() == RenderingRequest.ICON_RENDERING
- || request.getType() == RenderingRequest.PARTIAL_RENDERING) {
- Bitmap bmp = preset.apply(bitmap, mEnvironment);
- request.setBitmap(bmp);
- mFiltersManager.freeFilterResources(preset);
- }
+ if (request.getType() == RenderingRequest.FULL_RENDERING
+ || request.getType() == RenderingRequest.GEOMETRY_RENDERING
+ || request.getType() == RenderingRequest.FILTERS_RENDERING) {
+ updateOriginalAllocation(preset);
+ }
+ if (DEBUG) {
+ Log.v(LOGTAG, "after update, req bitmap (" + bitmap.getWidth() + "x" + bitmap.getHeight()
+ + " ? resizeOriginal (" + mResizedOriginalBitmap.getWidth() + "x"
+ + mResizedOriginalBitmap.getHeight());
+ }
+
+ if (request.getType() == RenderingRequest.FULL_RENDERING
+ || request.getType() == RenderingRequest.GEOMETRY_RENDERING) {
+ mOriginalAllocation.copyTo(bitmap);
+ } else if (request.getType() == RenderingRequest.FILTERS_RENDERING) {
+ mFiltersOnlyOriginalAllocation.copyTo(bitmap);
+ }
+
+ if (request.getType() == RenderingRequest.FULL_RENDERING
+ || request.getType() == RenderingRequest.FILTERS_RENDERING
+ || request.getType() == RenderingRequest.ICON_RENDERING
+ || request.getType() == RenderingRequest.PARTIAL_RENDERING) {
+ Bitmap bmp = preset.apply(bitmap, mEnvironment);
+ request.setBitmap(bmp);
+ mFiltersManager.freeFilterResources(preset);
+ }
+ }
}
public synchronized Bitmap renderFinalImage(Bitmap bitmap, ImagePreset preset) {
- setupEnvironment(preset);
- mEnvironment.setQuality(ImagePreset.QUALITY_FINAL);
- mEnvironment.setScaleFactor(1.0f);
- mFiltersManager.freeFilterResources(preset);
- bitmap = preset.applyGeometry(bitmap, mEnvironment);
- bitmap = preset.apply(bitmap, mEnvironment);
- return bitmap;
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return bitmap;
+ }
+ setupEnvironment(preset);
+ mEnvironment.setQuality(ImagePreset.QUALITY_FINAL);
+ mEnvironment.setScaleFactor(1.0f);
+ mFiltersManager.freeFilterResources(preset);
+ bitmap = preset.applyGeometry(bitmap, mEnvironment);
+ bitmap = preset.apply(bitmap, mEnvironment);
+ return bitmap;
+ }
}
public synchronized Bitmap renderGeometryIcon(Bitmap bitmap, ImagePreset preset) {
- setupEnvironment(preset);
- mEnvironment.setQuality(ImagePreset.QUALITY_PREVIEW);
- mFiltersManager.freeFilterResources(preset);
- bitmap = preset.applyGeometry(bitmap, mEnvironment);
- return bitmap;
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return bitmap;
+ }
+ setupEnvironment(preset);
+ mEnvironment.setQuality(ImagePreset.QUALITY_PREVIEW);
+ mFiltersManager.freeFilterResources(preset);
+ bitmap = preset.applyGeometry(bitmap, mEnvironment);
+ return bitmap;
+ }
}
public synchronized void compute(TripleBufferBitmap buffer, ImagePreset preset, int type) {
- if (DEBUG) {
- Log.v(LOGTAG, "compute preset " + preset);
- preset.showFilters();
- }
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return;
+ }
+ if (DEBUG) {
+ Log.v(LOGTAG, "compute preset " + preset);
+ preset.showFilters();
+ }
- String thread = Thread.currentThread().getName();
- long time = System.currentTimeMillis();
- setupEnvironment(preset);
- mFiltersManager.freeFilterResources(preset);
+ String thread = Thread.currentThread().getName();
+ long time = System.currentTimeMillis();
+ setupEnvironment(preset);
+ mFiltersManager.freeFilterResources(preset);
- Bitmap resizedOriginalBitmap = mResizedOriginalBitmap;
- if (updateOriginalAllocation(preset)) {
- resizedOriginalBitmap = mResizedOriginalBitmap;
- buffer.updateBitmaps(resizedOriginalBitmap);
- }
- Bitmap bitmap = buffer.getProducer();
- long time2 = System.currentTimeMillis();
+ Bitmap resizedOriginalBitmap = mResizedOriginalBitmap;
+ if (updateOriginalAllocation(preset)) {
+ resizedOriginalBitmap = mResizedOriginalBitmap;
+ buffer.updateBitmaps(resizedOriginalBitmap);
+ }
+ Bitmap bitmap = buffer.getProducer();
+ long time2 = System.currentTimeMillis();
- if (bitmap == null || (bitmap.getWidth() != resizedOriginalBitmap.getWidth())
- || (bitmap.getHeight() != resizedOriginalBitmap.getHeight())) {
- buffer.updateBitmaps(resizedOriginalBitmap);
- bitmap = buffer.getProducer();
- }
- mOriginalAllocation.copyTo(bitmap);
+ if (bitmap == null || (bitmap.getWidth() != resizedOriginalBitmap.getWidth())
+ || (bitmap.getHeight() != resizedOriginalBitmap.getHeight())) {
+ buffer.updateBitmaps(resizedOriginalBitmap);
+ bitmap = buffer.getProducer();
+ }
+ mOriginalAllocation.copyTo(bitmap);
- bitmap = preset.apply(bitmap, mEnvironment);
+ bitmap = preset.apply(bitmap, mEnvironment);
- mFiltersManager.freeFilterResources(preset);
+ mFiltersManager.freeFilterResources(preset);
- time = System.currentTimeMillis() - time;
- time2 = System.currentTimeMillis() - time2;
- if (DEBUG) {
- Log.v(LOGTAG, "Applying type " + type + " filters to bitmap "
- + bitmap + " (" + bitmap.getWidth() + " x " + bitmap.getHeight()
- + ") took " + time + " ms, " + time2 + " ms for the filter, on thread " + thread);
+ time = System.currentTimeMillis() - time;
+ time2 = System.currentTimeMillis() - time2;
+ if (DEBUG) {
+ Log.v(LOGTAG, "Applying type " + type + " filters to bitmap "
+ + bitmap + " (" + bitmap.getWidth() + " x " + bitmap.getHeight()
+ + ") took " + time + " ms, " + time2 + " ms for the filter, on thread " + thread);
+ }
}
}
@@ -292,11 +352,11 @@ public class CachingPipeline {
}
public synchronized boolean isInitialized() {
- return mOriginalBitmap != null;
+ return getRenderScriptContext() != null && mOriginalBitmap != null;
}
public boolean prepareRenderscriptAllocations(Bitmap bitmap) {
- RenderScript RS = ImageFilterRS.getRenderScriptContext();
+ RenderScript RS = getRenderScriptContext();
boolean needsUpdate = false;
if (mOutPixelsAllocation == null || mInPixelsAllocation == null ||
bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight) {
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
index cff071142..c76f7dda6 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java
@@ -29,22 +29,21 @@ public abstract class ImageFilterRS extends ImageFilter {
private static final String LOGTAG = "ImageFilterRS";
private boolean DEBUG = false;
- private static volatile RenderScript sRS = null;
- private static volatile Resources sResources = null;
private volatile boolean mResourcesLoaded = false;
- // This must be used inside block synchronized on ImageFilterRS class object
protected abstract void createFilter(android.content.res.Resources res,
float scaleFactor, int quality);
- // This must be used inside block synchronized on ImageFilterRS class object
protected abstract void runFilter();
- // This must be used inside block synchronized on ImageFilterRS class object
protected void update(Bitmap bitmap) {
getOutPixelsAllocation().copyTo(bitmap);
}
+ protected RenderScript getRenderScriptContext() {
+ return CachingPipeline.getRenderScriptContext();
+ }
+
protected Allocation getInPixelsAllocation() {
CachingPipeline pipeline = getEnvironment().getCachingPipeline();
return pipeline.getInPixelsAllocation();
@@ -61,24 +60,19 @@ public abstract class ImageFilterRS extends ImageFilter {
return bitmap;
}
try {
- synchronized(ImageFilterRS.class) {
- if (sRS == null) {
- Log.w(LOGTAG, "Cannot apply before calling createRenderScriptContext");
- return bitmap;
- }
- CachingPipeline pipeline = getEnvironment().getCachingPipeline();
- if (DEBUG) {
- Log.v(LOGTAG, "apply filter " + getName() + " in pipeline " + pipeline.getName());
- }
- pipeline.prepareRenderscriptAllocations(bitmap);
- createFilter(sResources, scaleFactor, quality);
- setResourcesLoaded(true);
- runFilter();
- update(bitmap);
- freeResources();
- if (DEBUG) {
- Log.v(LOGTAG, "DONE apply filter " + getName() + " in pipeline " + pipeline.getName());
- }
+ CachingPipeline pipeline = getEnvironment().getCachingPipeline();
+ if (DEBUG) {
+ Log.v(LOGTAG, "apply filter " + getName() + " in pipeline " + pipeline.getName());
+ }
+ pipeline.prepareRenderscriptAllocations(bitmap);
+ Resources rsc = pipeline.getResources();
+ createFilter(rsc, scaleFactor, quality);
+ setResourcesLoaded(true);
+ runFilter();
+ update(bitmap);
+ freeResources();
+ if (DEBUG) {
+ Log.v(LOGTAG, "DONE apply filter " + getName() + " in pipeline " + pipeline.getName());
}
} catch (android.renderscript.RSIllegalArgumentException e) {
Log.e(LOGTAG, "Illegal argument? " + e);
@@ -93,53 +87,32 @@ public abstract class ImageFilterRS extends ImageFilter {
return bitmap;
}
- public static synchronized RenderScript getRenderScriptContext() {
- return sRS;
- }
-
- public static synchronized void createRenderscriptContext(Activity context) {
- if( sRS != null) {
- Log.w(LOGTAG, "A prior RS context exists when calling setRenderScriptContext");
- destroyRenderScriptContext();
- }
- sRS = RenderScript.create(context);
- sResources = context.getResources();
- }
-
- public static synchronized void destroyRenderScriptContext() {
- sRS.destroy();
- sRS = null;
- sResources = null;
- }
-
- private static synchronized Allocation convertBitmap(Bitmap bitmap) {
- return Allocation.createFromBitmap(sRS, bitmap,
+ private static Allocation convertBitmap(Bitmap bitmap) {
+ return Allocation.createFromBitmap(CachingPipeline.getRenderScriptContext(), bitmap,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
}
- private static synchronized Allocation convertRGBAtoA(Bitmap bitmap) {
- Type.Builder tb_a8 = new Type.Builder(sRS, Element.A_8(sRS));
- ScriptC_grey greyConvert = new ScriptC_grey(sRS,
- sRS.getApplicationContext().getResources(), R.raw.grey);
+ private static Allocation convertRGBAtoA(Bitmap bitmap) {
+ RenderScript RS = CachingPipeline.getRenderScriptContext();
+ Type.Builder tb_a8 = new Type.Builder(RS, Element.A_8(RS));
+ ScriptC_grey greyConvert = new ScriptC_grey(RS,
+ RS.getApplicationContext().getResources(), R.raw.grey);
Allocation bitmapTemp = convertBitmap(bitmap);
- if (bitmapTemp.getType().getElement().isCompatible(Element.A_8(sRS))) {
+ if (bitmapTemp.getType().getElement().isCompatible(Element.A_8(RS))) {
return bitmapTemp;
}
tb_a8.setX(bitmapTemp.getType().getX());
tb_a8.setY(bitmapTemp.getType().getY());
- Allocation bitmapAlloc = Allocation.createTyped(sRS, tb_a8.create());
+ Allocation bitmapAlloc = Allocation.createTyped(RS, tb_a8.create());
greyConvert.forEach_RGBAtoA(bitmapTemp, bitmapAlloc);
return bitmapAlloc;
}
public Allocation loadScaledResourceAlpha(int resource, int inSampleSize) {
- Resources res = null;
- synchronized(ImageFilterRS.class) {
- res = sRS.getApplicationContext().getResources();
- }
+ Resources res = CachingPipeline.getResources();
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
options.inSampleSize = inSampleSize;
@@ -156,10 +129,7 @@ public abstract class ImageFilterRS extends ImageFilter {
}
public Allocation loadResource(int resource) {
- Resources res = null;
- synchronized(ImageFilterRS.class) {
- res = sRS.getApplicationContext().getResources();
- }
+ Resources res = CachingPipeline.getResources();
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeResource(
@@ -192,9 +162,7 @@ public abstract class ImageFilterRS extends ImageFilter {
if (!isResourcesLoaded()) {
return;
}
- synchronized(ImageFilterRS.class) {
- resetAllocations();
- setResourcesLoaded(false);
- }
+ resetAllocations();
+ setResourcesLoaded(false);
}
}