package com.android.gallery3d.filtershow.pipeline;
-import android.app.Activity;
+import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.support.v8.renderscript.Allocation;
-import android.support.v8.renderscript.RenderScript;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.renderscript.Allocation;
+import android.renderscript.RenderScript;
import android.util.Log;
+import com.android.gallery3d.filtershow.cache.BitmapCache;
import com.android.gallery3d.filtershow.cache.ImageLoader;
+import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.filters.FiltersManager;
-import com.android.gallery3d.filtershow.filters.ImageFilterGeometry;
-import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
+import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import java.util.Vector;
+
public class CachingPipeline implements PipelineInterface {
private static final String LOGTAG = "CachingPipeline";
private boolean DEBUG = false;
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;
private FilterEnvironment mEnvironment = new FilterEnvironment();
+ private CacheProcessing mCachedProcessing = new CacheProcessing();
+
private volatile Allocation mOriginalAllocation = null;
private volatile Allocation mFiltersOnlyOriginalAllocation = null;
private volatile int mWidth = 0;
private volatile int mHeight = 0;
- private volatile GeometryMetadata mPreviousGeometry = null;
private volatile float mPreviewScaleFactor = 1.0f;
private volatile float mHighResPreviewScaleFactor = 1.0f;
private volatile String mName = "";
- private ImageFilterGeometry mGeometry = null;
-
public CachingPipeline(FiltersManager filtersManager, String name) {
mFiltersManager = filtersManager;
mName = name;
return sRS;
}
- public static synchronized void createRenderscriptContext(Activity context) {
+ public static synchronized void createRenderscriptContext(Context 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;
}
public void stop() {
mFiltersOnlyOriginalAllocation.destroy();
mFiltersOnlyOriginalAllocation = null;
}
- mPreviousGeometry = null;
mPreviewScaleFactor = 1.0f;
mHighResPreviewScaleFactor = 1.0f;
private void setupEnvironment(ImagePreset preset, boolean highResPreview) {
mEnvironment.setPipeline(this);
mEnvironment.setFiltersManager(mFiltersManager);
+ mEnvironment.setBitmapCache(MasterImage.getImage().getBitmapCache());
if (highResPreview) {
mEnvironment.setScaleFactor(mHighResPreviewScaleFactor);
} else {
}
private synchronized boolean updateOriginalAllocation(ImagePreset preset) {
- Bitmap originalBitmap = mOriginalBitmap;
-
- if (originalBitmap == null) {
+ if (preset == null) {
return false;
}
+ Bitmap originalBitmap = mOriginalBitmap;
- GeometryMetadata geometry = preset.getGeometry();
- if (mPreviousGeometry != null && geometry.equals(mPreviousGeometry)) {
+ if (originalBitmap == null) {
return false;
}
- if (DEBUG) {
- Log.v(LOGTAG, "geometry has changed");
- }
-
RenderScript RS = getRenderScriptContext();
Allocation filtersOnlyOriginalAllocation = mFiltersOnlyOriginalAllocation;
originalAllocation.destroy();
}
- mPreviousGeometry = new GeometryMetadata(geometry);
return true;
}
+ public void renderHighres(RenderingRequest request) {
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return;
+ }
+ ImagePreset preset = request.getImagePreset();
+ setupEnvironment(preset, false);
+ Bitmap bitmap = MasterImage.getImage().getOriginalBitmapHighres();
+ if (bitmap == null) {
+ return;
+ }
+ bitmap = mEnvironment.getBitmapCopy(bitmap, BitmapCache.HIGHRES);
+ bitmap = preset.applyGeometry(bitmap, mEnvironment);
+
+ mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW);
+ Bitmap bmp = preset.apply(bitmap, mEnvironment);
+ if (!mEnvironment.needsStop()) {
+ request.setBitmap(bmp);
+ } else {
+ mEnvironment.cache(bmp);
+ }
+ mFiltersManager.freeFilterResources(preset);
+ }
+ }
+
+ public void renderGeometry(RenderingRequest request) {
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return;
+ }
+ ImagePreset preset = request.getImagePreset();
+ setupEnvironment(preset, false);
+ Bitmap bitmap = MasterImage.getImage().getOriginalBitmapHighres();
+ if (bitmap == null) {
+ return;
+ }
+ bitmap = mEnvironment.getBitmapCopy(bitmap, BitmapCache.GEOMETRY);
+ bitmap = preset.applyGeometry(bitmap, mEnvironment);
+ if (!mEnvironment.needsStop()) {
+ request.setBitmap(bitmap);
+ } else {
+ mEnvironment.cache(bitmap);
+ }
+ mFiltersManager.freeFilterResources(preset);
+ }
+ }
+
+ public void renderFilters(RenderingRequest request) {
+ synchronized (CachingPipeline.class) {
+ if (getRenderScriptContext() == null) {
+ return;
+ }
+ ImagePreset preset = request.getImagePreset();
+ setupEnvironment(preset, false);
+ Bitmap bitmap = MasterImage.getImage().getOriginalBitmapHighres();
+ if (bitmap == null) {
+ return;
+ }
+ bitmap = mEnvironment.getBitmapCopy(bitmap, BitmapCache.FILTERS);
+ bitmap = preset.apply(bitmap, mEnvironment);
+ if (!mEnvironment.needsStop()) {
+ request.setBitmap(bitmap);
+ } else {
+ mEnvironment.cache(bitmap);
+ }
+ mFiltersManager.freeFilterResources(preset);
+ }
+ }
+
public synchronized void render(RenderingRequest request) {
+ // TODO: cleanup/remove GEOMETRY / FILTERS paths
synchronized (CachingPipeline.class) {
if (getRenderScriptContext() == null) {
return;
}
- if (((request.getType() != RenderingRequest.PARTIAL_RENDERING
- && request.getType() != RenderingRequest.HIGHRES_RENDERING)
+ if ((request.getType() != RenderingRequest.PARTIAL_RENDERING
+ && request.getType() != RenderingRequest.ICON_RENDERING
&& request.getBitmap() == null)
|| request.getImagePreset() == null) {
return;
Bitmap bitmap = request.getBitmap();
ImagePreset preset = request.getImagePreset();
- setupEnvironment(preset,
- request.getType() != RenderingRequest.HIGHRES_RENDERING);
+ setupEnvironment(preset, true);
mFiltersManager.freeFilterResources(preset);
if (request.getType() == RenderingRequest.PARTIAL_RENDERING) {
MasterImage master = MasterImage.getImage();
bitmap = ImageLoader.getScaleOneImageForPreset(master.getActivity(),
+ mEnvironment.getBimapCache(),
master.getUri(), request.getBounds(),
request.getDestination());
if (bitmap == null) {
}
}
- if (request.getType() == RenderingRequest.HIGHRES_RENDERING) {
- bitmap = MasterImage.getImage().getOriginalBitmapHighres();
- if (bitmap != null) {
- bitmap = preset.applyGeometry(bitmap, mEnvironment);
- }
- }
-
if (request.getType() == RenderingRequest.FULL_RENDERING
|| request.getType() == RenderingRequest.GEOMETRY_RENDERING
|| request.getType() == RenderingRequest.FILTERS_RENDERING) {
updateOriginalAllocation(preset);
}
- if (DEBUG) {
+ if (DEBUG && bitmap != null) {
Log.v(LOGTAG, "after update, req bitmap (" + bitmap.getWidth() + "x" + bitmap.getHeight()
+ " ? resizeOriginal (" + mResizedOriginalBitmap.getWidth() + "x"
+ mResizedOriginalBitmap.getHeight());
|| request.getType() == RenderingRequest.FILTERS_RENDERING
|| request.getType() == RenderingRequest.ICON_RENDERING
|| request.getType() == RenderingRequest.PARTIAL_RENDERING
- || request.getType() == RenderingRequest.HIGHRES_RENDERING
|| request.getType() == RenderingRequest.STYLE_ICON_RENDERING) {
if (request.getType() == RenderingRequest.ICON_RENDERING) {
mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW);
}
+ if (request.getType() == RenderingRequest.ICON_RENDERING) {
+ Rect iconBounds = request.getIconBounds();
+ Bitmap source = MasterImage.getImage().getThumbnailBitmap();
+ if (iconBounds.width() > source.getWidth() * 2) {
+ source = MasterImage.getImage().getLargeThumbnailBitmap();
+ }
+ if (iconBounds != null) {
+ bitmap = mEnvironment.getBitmap(iconBounds.width(),
+ iconBounds.height(), BitmapCache.ICON);
+ Canvas canvas = new Canvas(bitmap);
+ Matrix m = new Matrix();
+ float minSize = Math.min(source.getWidth(), source.getHeight());
+ float maxSize = Math.max(iconBounds.width(), iconBounds.height());
+ float scale = maxSize / minSize;
+ m.setScale(scale, scale);
+ float dx = (iconBounds.width() - (source.getWidth() * scale))/2.0f;
+ float dy = (iconBounds.height() - (source.getHeight() * scale))/2.0f;
+ m.postTranslate(dx, dy);
+ canvas.drawBitmap(source, m, new Paint(Paint.FILTER_BITMAP_FLAG));
+ } else {
+ bitmap = mEnvironment.getBitmapCopy(source, BitmapCache.ICON);
+ }
+ }
Bitmap bmp = preset.apply(bitmap, mEnvironment);
if (!mEnvironment.needsStop()) {
request.setBitmap(bmp);
}
public Bitmap renderGeometryIcon(Bitmap bitmap, ImagePreset preset) {
- // Called by RenderRequest on the main thread
- // TODO: change this -- we should reuse a pool of bitmaps instead...
- if (mGeometry == null) {
- mGeometry = new ImageFilterGeometry();
- }
- mGeometry.useRepresentation(preset.getGeometry());
- return mGeometry.apply(bitmap, mPreviewScaleFactor,
- FilterEnvironment.QUALITY_PREVIEW);
+ return GeometryMathUtils.applyGeometryRepresentations(preset.getGeometryFilters(), bitmap);
}
- public synchronized void compute(SharedBuffer buffer, ImagePreset preset, int type) {
- 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, false);
- mFiltersManager.freeFilterResources(preset);
-
- Bitmap resizedOriginalBitmap = mResizedOriginalBitmap;
- if (updateOriginalAllocation(preset) || buffer.getProducer() == null) {
- resizedOriginalBitmap = mResizedOriginalBitmap;
- buffer.setProducer(resizedOriginalBitmap);
- mEnvironment.cache(buffer.getProducer());
- }
-
- Bitmap bitmap = buffer.getProducer().getBitmap();
- long time2 = System.currentTimeMillis();
-
- if (bitmap == null || (bitmap.getWidth() != resizedOriginalBitmap.getWidth())
- || (bitmap.getHeight() != resizedOriginalBitmap.getHeight())) {
- mEnvironment.cache(buffer.getProducer());
- buffer.setProducer(resizedOriginalBitmap);
- bitmap = buffer.getProducer().getBitmap();
- }
- mOriginalAllocation.copyTo(bitmap);
-
- Bitmap tmpbitmap = preset.apply(bitmap, mEnvironment);
- if (tmpbitmap != bitmap) {
- mEnvironment.cache(buffer.getProducer());
- buffer.setProducer(tmpbitmap);
- }
-
- 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);
- }
+ public void compute(SharedBuffer buffer, ImagePreset preset, int type) {
+ if (getRenderScriptContext() == null) {
+ return;
}
+ setupEnvironment(preset, false);
+ Vector<FilterRepresentation> filters = preset.getFilters();
+ Bitmap result = mCachedProcessing.process(mOriginalBitmap, filters, mEnvironment);
+ buffer.setProducer(result);
+ mEnvironment.cache(result);
}
public boolean needsRepaint() {