mPanelController.addPanel(R.id.colorsButton, R.id.colorsFxList, 3);
fillFx((LinearLayout) findViewById(R.id.listFilters), R.id.fxButton);
- LoadBordersTask loadBorders = new LoadBordersTask((LinearLayout) findViewById(R.id.listBorders));
- loadBorders.execute();
+ setupBorders();
fillGeometry();
fillFilters();
mLoadBitmapTask.execute(uri);
}
- private class LoadBordersTask extends AsyncTask<Void, Boolean, Boolean> {
- Vector<FilterRepresentation> mBorders;
- LinearLayout mList;
-
- public LoadBordersTask(LinearLayout list) {
- mList = list;
- mBorders = new Vector<FilterRepresentation>();
- }
-
- @Override
- protected Boolean doInBackground(Void... params) {
- mBorders.add(new FilterImageBorderRepresentation(0));
- mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5));
- mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush));
- mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge));
- mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e));
- mBorders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape));
- mBorders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, 0));
- mBorders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, mImageBorderSize));
- mBorders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, 0));
- mBorders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, mImageBorderSize));
- int creamColor = Color.argb(255, 237, 237, 227);
- mBorders.add(new FilterColorBorderRepresentation(creamColor, mImageBorderSize, 0));
- mBorders.add(new FilterColorBorderRepresentation(creamColor, mImageBorderSize, mImageBorderSize));
- return true;
- }
-
- @Override
- protected void onPostExecute(Boolean result) {
- if (!result) {
- return;
+ private void setupBorders() {
+ LinearLayout list = (LinearLayout) findViewById(R.id.listBorders);
+ Vector<FilterRepresentation> borders = new Vector<FilterRepresentation>();
+ borders.add(new FilterImageBorderRepresentation(0));
+ borders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5));
+ borders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush));
+ borders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge));
+ borders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e));
+ borders.add(new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape));
+ borders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, 0));
+ borders.add(new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize,
+ mImageBorderSize));
+ borders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, 0));
+ borders.add(new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize,
+ mImageBorderSize));
+ int creamColor = Color.argb(255, 237, 237, 227);
+ borders.add(new FilterColorBorderRepresentation(creamColor, mImageBorderSize, 0));
+ borders.add(new FilterColorBorderRepresentation(creamColor, mImageBorderSize,
+ mImageBorderSize));
+ for (int i = 0; i < borders.size(); i++) {
+ FilterRepresentation filter = borders.elementAt(i);
+ filter.setName(getString(R.string.borders));
+ if (i == 0) {
+ filter.setName(getString(R.string.none));
}
- for (int i = 0; i < mBorders.size(); i++) {
- FilterRepresentation filter = mBorders.elementAt(i);
- filter.setName(getString(R.string.borders));
- if (i == 0) {
- filter.setName(getString(R.string.none));
- }
- ImageButton borderButton = (ImageButton) findViewById(R.id.borderButton);
- FilterIconButton b = setupFilterRepresentationButton(filter, mList, borderButton);
- if (i == 0) {
- mNullBorderFilter = b;
- mNullBorderFilter.setSelected(true);
- }
+ ImageButton borderButton = (ImageButton) findViewById(R.id.borderButton);
+ FilterIconButton b = setupFilterRepresentationButton(filter, list, borderButton);
+ if (i == 0) {
+ mNullBorderFilter = b;
+ mNullBorderFilter.setSelected(true);
}
- fillButtonIcons();
}
}
float previewScale = (float) largeBitmap.getWidth() / (float) mImageLoader.getOriginalBounds().width();
pipeline.setPreviewScaleFactor(previewScale);
- fillButtonIcons();
MasterImage.getImage().setOriginalGeometry(largeBitmap);
mLoadBitmapTask = null;
} else if (mAction == TINY_PLANET_ACTION) {
mPanelController.showComponent(findViewById(EditorTinyPlanet.ID));
}
-
+ pipeline.turnOnPipeline(true);
super.onPostExecute(result);
}
}).execute();
}
- private void fillButtonIcons() {
- Bitmap bmap = mImageLoader.getOriginalBitmapSmall();
- if (bmap != null && bmap.getWidth() > 0 && bmap.getHeight() > 0) {
- float w = bmap.getWidth();
- float h = bmap.getHeight();
- float f = mIconSeedSize / Math.min(w, h);
- w = w * f;
- h = h * f;
- bmap = Bitmap.createScaledBitmap(bmap, (int) w, (int) h, true);
-
- LinearLayout listColors = (LinearLayout) findViewById(R.id.listColorsFx);
- int num_colors_buttons = listColors.getChildCount();
- for (int i = 0; i < num_colors_buttons; i++) {
- FilterIconButton b = (FilterIconButton) listColors.getChildAt(i);
- b.setIcon(bmap);
- }
-
- LinearLayout listFilters = (LinearLayout) findViewById(R.id.listFilters);
- int num_filters_buttons = listFilters.getChildCount();
- for (int i = 0; i < num_filters_buttons; i++) {
- FilterIconButton b = (FilterIconButton) listFilters.getChildAt(i);
- b.setIcon(bmap);
- }
-
- LinearLayout listBorders = (LinearLayout) findViewById(R.id.listBorders);
- int num_borders_buttons = listBorders.getChildCount();
- for (int i = 0; i < num_borders_buttons; i++) {
- FilterIconButton b = (FilterIconButton) listBorders.getChildAt(i);
- b.setIcon(bmap);
- }
-
- }
- }
-
@Override
protected void onDestroy() {
if (mLoadBitmapTask != null) {
ImageFilterRS.destroyRenderScriptContext();
FilteringPipeline.reset();
ImageFilter.resetStatics();
+ FiltersManager.getPreviewManager().freeRSFilterScripts();
+ FiltersManager.getManager().freeRSFilterScripts();
FiltersManager.reset();
super.onDestroy();
}
private static volatile FilteringPipeline sPipeline = null;
private static final String LOGTAG = "FilteringPipeline";
- private ImagePreset mPreviousGeometryPreset = null;
- private ImagePreset mPreviousFiltersPreset = null;
- private GeometryMetadata mPreviousGeometry = null;
- private float mPreviewScaleFactor = 1.0f;
+ private volatile GeometryMetadata mPreviousGeometry = null;
+ private volatile float mPreviewScaleFactor = 1.0f;
+ private volatile boolean mPipelineIsOn = false;
- private Bitmap mOriginalBitmap = null;
- private Bitmap mResizedOriginalBitmap = null;
+ private volatile Bitmap mOriginalBitmap = null;
+ private volatile Bitmap mResizedOriginalBitmap = null;
private boolean DEBUG = false;
private final static int COMPUTE_RENDERING_REQUEST = 3;
private final static int COMPUTE_PARTIAL_RENDERING_REQUEST = 4;
- private boolean mHasUnhandledPreviewRequest = false;
+ private volatile boolean mHasUnhandledPreviewRequest = false;
private Handler mProcessingHandler = null;
private final Handler mUIHandler = new Handler() {
@Override
public boolean handleMessage(Message msg) {
+ if (!mPipelineIsOn) {
+ return false;
+ }
switch (msg.what) {
case COMPUTE_PRESET: {
ImagePreset preset = (ImagePreset) msg.obj;
private static float RESIZE_FACTOR = 0.8f;
private static float MAX_PROCESS_TIME = 100; // in ms
private static long HIRES_DELAY = 100; // in ms
- private float mResizeFactor = 1.0f;
- private long mResizeTime = 0;
- private Allocation mOriginalAllocation = null;
- private Allocation mFiltersOnlyOriginalAllocation = null;
+ private volatile Allocation mOriginalAllocation = null;
+ private volatile Allocation mFiltersOnlyOriginalAllocation = null;
private FilteringPipeline() {
mHandlerThread = new HandlerThread("FilteringPipeline",
RenderScript RS = ImageFilterRS.getRenderScriptContext();
if (mFiltersOnlyOriginalAllocation != null) {
mFiltersOnlyOriginalAllocation.destroy();
+ mFiltersOnlyOriginalAllocation = null;
}
mFiltersOnlyOriginalAllocation = Allocation.createFromBitmap(RS, mOriginalBitmap,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
if (mOriginalAllocation != null) {
mOriginalAllocation.destroy();
+ mOriginalAllocation = null;
}
mResizedOriginalBitmap = preset.applyGeometry(mOriginalBitmap);
mOriginalAllocation = Allocation.createFromBitmap(RS, mResizedOriginalBitmap,
}
private void setPresetParameters(ImagePreset preset) {
- preset.setScaleFactor(mPreviewScaleFactor);
- if (mPreviewScaleFactor < 1.0f) {
+ float scale = mPreviewScaleFactor;
+ preset.setScaleFactor(scale);
+ if (scale < 1.0f) {
preset.setQuality(ImagePreset.QUALITY_PREVIEW);
} else {
preset.setQuality(ImagePreset.QUALITY_PREVIEW);
return "UNKNOWN TYPE!";
}
- private void render(RenderingRequest request) {
+ private synchronized void render(RenderingRequest request) {
if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
&& request.getBitmap() == null)
|| request.getImagePreset() == null) {
}
- private void compute(TripleBufferBitmap buffer, ImagePreset preset, int type) {
+ private synchronized void compute(TripleBufferBitmap buffer, ImagePreset preset, int type) {
if (DEBUG) {
Log.v(LOGTAG, "compute preset " + preset);
preset.showFilters();
+ bitmap + " (" + bitmap.getWidth() + " x " + bitmap.getHeight()
+ ") took " + time + " ms, " + time2 + " ms for the filter, on thread " + thread);
}
- if (type == COMPUTE_PRESET) {
- if (mResizeFactor > 0.6 && time > MAX_PROCESS_TIME && (System.currentTimeMillis() + 1000 > mResizeTime)) {
- mResizeTime = System.currentTimeMillis();
- mResizeFactor *= RESIZE_FACTOR;
- }
- }
}
private synchronized boolean needsRepaint() {
sPipeline.mHandlerThread.quit();
sPipeline = null;
}
+
+ public void turnOnPipeline(boolean t) {
+ mPipelineIsOn = t;
+ }
}
private static String LOGTAG = "TripleBufferBitmap";
- private Bitmap mBitmaps[] = new Bitmap[3];
- private Bitmap mProducer = null;
- private Bitmap mConsumer = null;
- private Bitmap mIntermediate = null;
- private boolean mNeedsSwap = false;
+ private volatile Bitmap mBitmaps[] = new Bitmap[3];
+ private volatile Bitmap mProducer = null;
+ private volatile Bitmap mConsumer = null;
+ private volatile Bitmap mIntermediate = null;
+ private volatile boolean mNeedsSwap = false;
private final Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
- private boolean mNeedsRepaint = true;
+ private volatile boolean mNeedsRepaint = true;
public TripleBufferBitmap() {
}
}
+ public void freeRSFilterScripts() {
+ for (Class c : mFilters.keySet()) {
+ ImageFilter filter = mFilters.get(c);
+ if (filter != null && filter instanceof ImageFilterRS) {
+ ((ImageFilterRS) filter).resetScripts();
+ }
+ }
+ }
+
protected void addFilterClasses(Vector<Class> filters) {
filters.add(ImageFilterTinyPlanet.class);
filters.add(ImageFilterRedEye.class);
BitmapFactory.Options o = new BitmapFactory.Options();
o.inScaled = false;
mFxBitmapId = getParameters().getBitmapResource();
- mFxBitmap = BitmapFactory.decodeResource(mResources, mFxBitmapId, o);
+ if (mFxBitmapId != 0) {
+ mFxBitmap = BitmapFactory.decodeResource(mResources, mFxBitmapId, o);
+ } else {
+ Log.w(LOGTAG, "bad resource for filter: " + mName);
+ }
}
if (mFxBitmap == null) {
mResourcesLoaded = resourcesLoaded;
}
- // TODO:
- // Ideally, every filter would destroy _every_ renderscript allocation,
- // script, and anything else that depends on a certain RS context here.
+ /**
+ * Bitmaps and RS Allocations should be cleared here
+ */
abstract protected void resetAllocations();
+ /**
+ * RS Script objects (and all other RS objects) should be cleared here
+ */
+ abstract protected void resetScripts();
+
public void freeResources() {
if (!isResourcesLoaded()) {
return;
mParameters = parameters;
}
+ @Override
protected void resetAllocations() {
// nothing to do
}
@Override
+ protected void resetScripts() {
+ if (mScript != null) {
+ mScript.destroy();
+ mScript = null;
+ }
+ }
+
+ @Override
protected void createFilter(android.content.res.Resources res, float scaleFactor,
int quality) {
int w = mInPixelsAllocation.getType().getX();
mScript.set_gHeight(h);
}
- private void computeKernel(){
+ private void computeKernel() {
float p1 = mParameters.getValue() * mScaleFactor;
float value = p1 / 100.0f;
float f[] = new float[9];
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
return;
}
mIconBitmap = null;
- postNewIconRenderRequest();
+ invalidate();
}
private void postNewIconRenderRequest() {