From f51cdda5060a742863d0d74d57040d48d9ab394d Mon Sep 17 00:00:00 2001 From: nicolasroard Date: Tue, 2 Jul 2013 15:46:23 -0700 Subject: Move classes to pipeline package Change-Id: I9d664537d845d9daeb352c8006d0296a3f546dca --- .../gallery3d/filtershow/FilterShowActivity.java | 6 +- .../filtershow/cache/CachingPipeline.java | 462 -------------- .../filtershow/cache/FilteringPipeline.java | 245 ------- .../gallery3d/filtershow/cache/ImageLoader.java | 2 +- .../filtershow/cache/RenderingRequest.java | 170 ----- .../filtershow/cache/RenderingRequestCaller.java | 21 - .../gallery3d/filtershow/category/Action.java | 6 +- .../filtershow/category/CategoryAdapter.java | 5 +- .../filtershow/controller/BasicParameterStyle.java | 3 +- .../filtershow/controller/FilterView.java | 2 +- .../filtershow/controller/ParameterStyles.java | 2 +- .../filtershow/controller/StyleChooser.java | 4 +- .../gallery3d/filtershow/editors/Editor.java | 3 +- .../filtershow/filters/BaseFiltersManager.java | 2 +- .../gallery3d/filtershow/filters/ImageFilter.java | 4 +- .../filtershow/filters/ImageFilterDraw.java | 3 +- .../filtershow/filters/ImageFilterRS.java | 2 +- .../filtershow/filters/ImageFilterTinyPlanet.java | 4 +- .../filtershow/filters/ImageFilterVignette.java | 2 +- .../gallery3d/filtershow/history/HistoryItem.java | 2 +- .../filtershow/imageshow/ImageGeometry.java | 2 +- .../gallery3d/filtershow/imageshow/ImageShow.java | 2 +- .../filtershow/imageshow/MasterImage.java | 8 +- .../gallery3d/filtershow/pipeline/Buffer.java | 2 - .../filtershow/pipeline/CachingPipeline.java | 459 ++++++++++++++ .../filtershow/pipeline/FilterEnvironment.java | 167 +++++ .../filtershow/pipeline/FilteringPipeline.java | 240 +++++++ .../gallery3d/filtershow/pipeline/ImagePreset.java | 700 ++++++++++++++++++++ .../filtershow/pipeline/PipelineInterface.java | 31 + .../filtershow/pipeline/RenderingRequest.java | 168 +++++ .../pipeline/RenderingRequestCaller.java | 21 + .../filtershow/pipeline/SharedPreset.java | 2 - .../filtershow/presets/FilterEnvironment.java | 168 ----- .../gallery3d/filtershow/presets/ImagePreset.java | 702 --------------------- .../filtershow/presets/PipelineInterface.java | 31 - .../gallery3d/filtershow/tools/SaveCopyTask.java | 4 +- .../gallery3d/filtershow/tools/XmpPresets.java | 2 +- .../gallery3d/filtershow/ui/FilterIconButton.java | 7 +- .../gallery3d/filtershow/ui/ImageCurves.java | 4 +- 39 files changed, 1821 insertions(+), 1849 deletions(-) delete mode 100644 src/com/android/gallery3d/filtershow/cache/CachingPipeline.java delete mode 100644 src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java delete mode 100644 src/com/android/gallery3d/filtershow/cache/RenderingRequest.java delete mode 100644 src/com/android/gallery3d/filtershow/cache/RenderingRequestCaller.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/CachingPipeline.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/FilterEnvironment.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/PipelineInterface.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/RenderingRequest.java create mode 100644 src/com/android/gallery3d/filtershow/pipeline/RenderingRequestCaller.java delete mode 100644 src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java delete mode 100644 src/com/android/gallery3d/filtershow/presets/ImagePreset.java delete mode 100644 src/com/android/gallery3d/filtershow/presets/PipelineInterface.java (limited to 'src') diff --git a/src/com/android/gallery3d/filtershow/FilterShowActivity.java b/src/com/android/gallery3d/filtershow/FilterShowActivity.java index 0d9205a86..3fa6d1bb8 100644 --- a/src/com/android/gallery3d/filtershow/FilterShowActivity.java +++ b/src/com/android/gallery3d/filtershow/FilterShowActivity.java @@ -54,8 +54,8 @@ 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.pipeline.CachingPipeline; +import com.android.gallery3d.filtershow.pipeline.FilteringPipeline; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.category.Action; import com.android.gallery3d.filtershow.category.CategoryAdapter; @@ -85,7 +85,7 @@ import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; import com.android.gallery3d.filtershow.imageshow.ImageCrop; import com.android.gallery3d.filtershow.imageshow.ImageShow; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.provider.SharedImageProvider; import com.android.gallery3d.filtershow.state.StateAdapter; import com.android.gallery3d.filtershow.tools.SaveCopyTask; diff --git a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java b/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java deleted file mode 100644 index 5a4267efa..000000000 --- a/src/com/android/gallery3d/filtershow/cache/CachingPipeline.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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; -import android.util.Log; - -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.MasterImage; -import com.android.gallery3d.filtershow.pipeline.SharedBuffer; -import com.android.gallery3d.filtershow.presets.FilterEnvironment; -import com.android.gallery3d.filtershow.presets.ImagePreset; -import com.android.gallery3d.filtershow.presets.PipelineInterface; - -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 volatile Allocation mOriginalAllocation = null; - private volatile Allocation mFiltersOnlyOriginalAllocation = null; - - protected volatile Allocation mInPixelsAllocation; - protected volatile Allocation mOutPixelsAllocation; - 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; - } - - 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() { - if (sRS != null) { - sRS.destroy(); - } - sRS = null; - sResources = null; - } - - public void stop() { - mEnvironment.setStop(true); - } - - 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; - mHighResPreviewScaleFactor = 1.0f; - - destroyPixelAllocations(); - } - } - - public Resources getResources() { - return sRS.getApplicationContext().getResources(); - } - - private synchronized void destroyPixelAllocations() { - if (DEBUG) { - Log.v(LOGTAG, "destroyPixelAllocations in " + getName()); - } - if (mInPixelsAllocation != null) { - mInPixelsAllocation.destroy(); - mInPixelsAllocation = null; - } - if (mOutPixelsAllocation != null) { - mOutPixelsAllocation.destroy(); - mOutPixelsAllocation = null; - } - mWidth = 0; - mHeight = 0; - } - - private String getType(RenderingRequest request) { - if (request.getType() == RenderingRequest.ICON_RENDERING) { - return "ICON_RENDERING"; - } - if (request.getType() == RenderingRequest.FILTERS_RENDERING) { - return "FILTERS_RENDERING"; - } - if (request.getType() == RenderingRequest.FULL_RENDERING) { - return "FULL_RENDERING"; - } - if (request.getType() == RenderingRequest.GEOMETRY_RENDERING) { - return "GEOMETRY_RENDERING"; - } - if (request.getType() == RenderingRequest.PARTIAL_RENDERING) { - return "PARTIAL_RENDERING"; - } - if (request.getType() == RenderingRequest.HIGHRES_RENDERING) { - return "HIGHRES_RENDERING"; - } - return "UNKNOWN TYPE!"; - } - - private void setupEnvironment(ImagePreset preset, boolean highResPreview) { - mEnvironment.setPipeline(this); - mEnvironment.setFiltersManager(mFiltersManager); - if (highResPreview) { - mEnvironment.setScaleFactor(mHighResPreviewScaleFactor); - } else { - mEnvironment.setScaleFactor(mPreviewScaleFactor); - } - mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); - mEnvironment.setImagePreset(preset); - mEnvironment.setStop(false); - } - - public void setOriginal(Bitmap bitmap) { - mOriginalBitmap = bitmap; - Log.v(LOGTAG,"setOriginal, size " + bitmap.getWidth() + " x " + bitmap.getHeight()); - ImagePreset preset = MasterImage.getImage().getPreset(); - setupEnvironment(preset, false); - updateOriginalAllocation(preset); - } - - private synchronized boolean updateOriginalAllocation(ImagePreset preset) { - Bitmap originalBitmap = mOriginalBitmap; - - if (originalBitmap == null) { - return false; - } - - GeometryMetadata geometry = preset.getGeometry(); - if (mPreviousGeometry != null && geometry.equals(mPreviousGeometry)) { - return false; - } - - if (DEBUG) { - Log.v(LOGTAG, "geometry has changed"); - } - - RenderScript RS = getRenderScriptContext(); - - Allocation filtersOnlyOriginalAllocation = mFiltersOnlyOriginalAllocation; - mFiltersOnlyOriginalAllocation = Allocation.createFromBitmap(RS, originalBitmap, - Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); - if (filtersOnlyOriginalAllocation != null) { - filtersOnlyOriginalAllocation.destroy(); - } - - Allocation originalAllocation = mOriginalAllocation; - mResizedOriginalBitmap = preset.applyGeometry(originalBitmap, mEnvironment); - mOriginalAllocation = Allocation.createFromBitmap(RS, mResizedOriginalBitmap, - Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); - if (originalAllocation != null) { - originalAllocation.destroy(); - } - - mPreviousGeometry = new GeometryMetadata(geometry); - return true; - } - - public synchronized void render(RenderingRequest request) { - synchronized (CachingPipeline.class) { - if (getRenderScriptContext() == null) { - return; - } - if (((request.getType() != RenderingRequest.PARTIAL_RENDERING - && request.getType() != RenderingRequest.HIGHRES_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, - request.getType() != RenderingRequest.HIGHRES_RENDERING); - 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)); - 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.HIGHRES_RENDERING) { - ImageLoader loader = MasterImage.getImage().getImageLoader(); - bitmap = loader.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) { - 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 - || request.getType() == RenderingRequest.HIGHRES_RENDERING - || request.getType() == RenderingRequest.STYLE_ICON_RENDERING) { - - if (request.getType() == RenderingRequest.ICON_RENDERING) { - mEnvironment.setQuality(FilterEnvironment.QUALITY_ICON); - } else { - mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); - } - - Bitmap bmp = preset.apply(bitmap, mEnvironment); - if (!mEnvironment.needsStop()) { - request.setBitmap(bmp); - } - mFiltersManager.freeFilterResources(preset); - } - } - } - - 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); - boolean copyOut = false; - if (preset.nbFilters() > 0) { - copyOut = true; - } - preset.applyBorder(in, out, copyOut, mEnvironment); - } - } - - public synchronized Bitmap renderFinalImage(Bitmap bitmap, ImagePreset preset) { - synchronized (CachingPipeline.class) { - if (getRenderScriptContext() == null) { - return bitmap; - } - setupEnvironment(preset, false); - mEnvironment.setQuality(FilterEnvironment.QUALITY_FINAL); - mEnvironment.setScaleFactor(1.0f); - mFiltersManager.freeFilterResources(preset); - bitmap = preset.applyGeometry(bitmap, mEnvironment); - bitmap = preset.apply(bitmap, mEnvironment); - return bitmap; - } - } - - 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); - } - - 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 boolean needsRepaint() { - SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer(); - return buffer.checkRepaintNeeded(); - } - - public void setPreviewScaleFactor(float previewScaleFactor) { - mPreviewScaleFactor = previewScaleFactor; - } - - public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) { - mHighResPreviewScaleFactor = highResPreviewScaleFactor; - } - - public synchronized boolean isInitialized() { - return getRenderScriptContext() != null && mOriginalBitmap != null; - } - - public boolean prepareRenderscriptAllocations(Bitmap bitmap) { - RenderScript RS = getRenderScriptContext(); - boolean needsUpdate = false; - if (mOutPixelsAllocation == null || mInPixelsAllocation == null || - bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight) { - destroyPixelAllocations(); - Bitmap bitmapBuffer = bitmap; - if (bitmap.getConfig() == null || bitmap.getConfig() != BITMAP_CONFIG) { - bitmapBuffer = bitmap.copy(BITMAP_CONFIG, true); - } - mOutPixelsAllocation = Allocation.createFromBitmap(RS, bitmapBuffer, - Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); - mInPixelsAllocation = Allocation.createTyped(RS, - mOutPixelsAllocation.getType()); - needsUpdate = true; - } - if (RS != null) { - mInPixelsAllocation.copyFrom(bitmap); - } - if (bitmap.getWidth() != mWidth - || bitmap.getHeight() != mHeight) { - mWidth = bitmap.getWidth(); - mHeight = bitmap.getHeight(); - needsUpdate = true; - } - if (DEBUG) { - Log.v(LOGTAG, "prepareRenderscriptAllocations: " + needsUpdate + " in " + getName()); - } - return needsUpdate; - } - - public synchronized Allocation getInPixelsAllocation() { - return mInPixelsAllocation; - } - - public synchronized Allocation getOutPixelsAllocation() { - return mOutPixelsAllocation; - } - - public String getName() { - return mName; - } - - public RenderScript getRSContext() { - return CachingPipeline.getRenderScriptContext(); - } -} diff --git a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java b/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java deleted file mode 100644 index 3232db774..000000000 --- a/src/com/android/gallery3d/filtershow/cache/FilteringPipeline.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.cache; - -import android.graphics.Bitmap; -import android.os.*; -import android.os.Process; -import android.support.v8.renderscript.*; -import android.util.Log; - -import com.android.gallery3d.filtershow.filters.FiltersManager; -import com.android.gallery3d.filtershow.filters.ImageFilterRS; -import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; -import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.pipeline.SharedBuffer; -import com.android.gallery3d.filtershow.pipeline.SharedPreset; -import com.android.gallery3d.filtershow.presets.ImagePreset; - -public class FilteringPipeline implements Handler.Callback { - - private static volatile FilteringPipeline sPipeline = null; - private static final String LOGTAG = "FilteringPipeline"; - private boolean DEBUG = false; - - private static long HIRES_DELAY = 300; // in ms - - private volatile boolean mPipelineIsOn = false; - - private CachingPipeline mAccessoryPipeline = null; - private CachingPipeline mPreviewPipeline = null; - private CachingPipeline mHighresPreviewPipeline = null; - - private HandlerThread mHandlerThread = null; - private final static int NEW_PRESET = 0; - private final static int NEW_RENDERING_REQUEST = 1; - private final static int COMPUTE_PRESET = 2; - private final static int COMPUTE_RENDERING_REQUEST = 3; - private final static int COMPUTE_PARTIAL_RENDERING_REQUEST = 4; - private final static int COMPUTE_HIGHRES_RENDERING_REQUEST = 5; - - private volatile boolean mHasUnhandledPreviewRequest = false; - - private String getType(int value) { - if (value == COMPUTE_RENDERING_REQUEST) { - return "COMPUTE_RENDERING_REQUEST"; - } - if (value == COMPUTE_PARTIAL_RENDERING_REQUEST) { - return "COMPUTE_PARTIAL_RENDERING_REQUEST"; - } - if (value == COMPUTE_HIGHRES_RENDERING_REQUEST) { - return "COMPUTE_HIGHRES_RENDERING_REQUEST"; - } - return "UNKNOWN TYPE"; - } - - private Handler mProcessingHandler = null; - private final Handler mUIHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case NEW_PRESET: { - MasterImage.getImage().notifyObservers(); - if (mHasUnhandledPreviewRequest) { - updatePreviewBuffer(); - } - break; - } - case NEW_RENDERING_REQUEST: { - RenderingRequest request = (RenderingRequest) msg.obj; - request.markAvailable(); - break; - } - } - } - }; - - @Override - public boolean handleMessage(Message msg) { - if (!mPipelineIsOn) { - return false; - } - switch (msg.what) { - case COMPUTE_PRESET: { - SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer(); - SharedPreset preset = MasterImage.getImage().getPreviewPreset(); - ImagePreset renderingPreset = preset.dequeuePreset(); - if (renderingPreset != null) { - mPreviewPipeline.compute(buffer, renderingPreset, COMPUTE_PRESET); - // set the preset we used in the buffer for later inspection UI-side - buffer.getProducer().setPreset(renderingPreset); - buffer.getProducer().sync(); - buffer.swapProducer(); // push back the result - Message uimsg = mUIHandler.obtainMessage(NEW_PRESET); - mUIHandler.sendMessage(uimsg); - } - break; - } - case COMPUTE_RENDERING_REQUEST: - case COMPUTE_PARTIAL_RENDERING_REQUEST: - case COMPUTE_HIGHRES_RENDERING_REQUEST: { - - if (DEBUG) { - Log.v(LOGTAG, "Compute Request: " + getType(msg.what)); - } - - RenderingRequest request = (RenderingRequest) msg.obj; - if (msg.what == COMPUTE_HIGHRES_RENDERING_REQUEST) { - mHighresPreviewPipeline.render(request); - } else { - mAccessoryPipeline.render(request); - } - if (request.getBitmap() != null) { - Message uimsg = mUIHandler.obtainMessage(NEW_RENDERING_REQUEST); - uimsg.obj = request; - mUIHandler.sendMessage(uimsg); - } - break; - } - } - return false; - } - - private FilteringPipeline() { - mHandlerThread = new HandlerThread("FilteringPipeline", - Process.THREAD_PRIORITY_FOREGROUND); - mHandlerThread.start(); - mProcessingHandler = new Handler(mHandlerThread.getLooper(), this); - mAccessoryPipeline = new CachingPipeline( - FiltersManager.getManager(), "Accessory"); - mPreviewPipeline = new CachingPipeline( - FiltersManager.getPreviewManager(), "Preview"); - mHighresPreviewPipeline = new CachingPipeline( - FiltersManager.getHighresManager(), "Highres"); - } - - public synchronized static FilteringPipeline getPipeline() { - if (sPipeline == null) { - sPipeline = new FilteringPipeline(); - } - return sPipeline; - } - - public void setOriginal(Bitmap bitmap) { - if (mPipelineIsOn) { - Log.e(LOGTAG, "setOriginal called after pipeline initialization!"); - return; - } - mAccessoryPipeline.setOriginal(bitmap); - mPreviewPipeline.setOriginal(bitmap); - mHighresPreviewPipeline.setOriginal(bitmap); - } - - public void postRenderingRequest(RenderingRequest request) { - if (!mPipelineIsOn) { - return; - } - int type = COMPUTE_RENDERING_REQUEST; - if (request.getType() == RenderingRequest.PARTIAL_RENDERING) { - type = COMPUTE_PARTIAL_RENDERING_REQUEST; - } - if (request.getType() == RenderingRequest.HIGHRES_RENDERING) { - type = COMPUTE_HIGHRES_RENDERING_REQUEST; - ImageLoader imageLoader = MasterImage.getImage().getImageLoader(); - if (imageLoader.getOriginalBitmapHighres() == null) { - return; - } - } - Message msg = mProcessingHandler.obtainMessage(type); - msg.obj = request; - if (type == COMPUTE_PARTIAL_RENDERING_REQUEST - || type == COMPUTE_HIGHRES_RENDERING_REQUEST) { - if (mProcessingHandler.hasMessages(msg.what)) { - mProcessingHandler.removeMessages(msg.what); - } - mProcessingHandler.sendMessageDelayed(msg, HIRES_DELAY); - } else { - mProcessingHandler.sendMessage(msg); - } - } - - public void updatePreviewBuffer() { - if (!mPipelineIsOn) { - return; - } - mHasUnhandledPreviewRequest = true; - mHighresPreviewPipeline.stop(); - if (mProcessingHandler.hasMessages(COMPUTE_PRESET)) { - return; - } - if (!mPreviewPipeline.needsRepaint()) { - return; - } - if (MasterImage.getImage().getPreset() == null) { - return; - } - Message msg = mProcessingHandler.obtainMessage(COMPUTE_PRESET); - msg.obj = MasterImage.getImage().getPreset(); - mHasUnhandledPreviewRequest = false; - mProcessingHandler.sendMessageAtFrontOfQueue(msg); - } - - public void setPreviewScaleFactor(float previewScaleFactor) { - mAccessoryPipeline.setPreviewScaleFactor(previewScaleFactor); - mPreviewPipeline.setPreviewScaleFactor(previewScaleFactor); - mHighresPreviewPipeline.setPreviewScaleFactor(previewScaleFactor); - } - - public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) { - mAccessoryPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor); - mPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor); - mHighresPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor); - } - - public static synchronized void reset() { - sPipeline.mAccessoryPipeline.reset(); - sPipeline.mPreviewPipeline.reset(); - sPipeline.mHighresPreviewPipeline.reset(); - sPipeline.mHandlerThread.quit(); - sPipeline = null; - } - - public void turnOnPipeline(boolean t) { - mPipelineIsOn = t; - if (mPipelineIsOn) { - assert(mPreviewPipeline.isInitialized()); - assert(mAccessoryPipeline.isInitialized()); - assert(mHighresPreviewPipeline.isInitialized()); - updatePreviewBuffer(); - } - } -} diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java index a7149d1f0..85cebab4d 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -39,7 +39,7 @@ import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.history.HistoryManager; import com.android.gallery3d.filtershow.imageshow.ImageShow; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.tools.SaveCopyTask; import com.android.gallery3d.util.XmpUtilHelper; diff --git a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java b/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java deleted file mode 100644 index e5bc411de..000000000 --- a/src/com/android/gallery3d/filtershow/cache/RenderingRequest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.cache; - -import android.graphics.Bitmap; -import android.graphics.Rect; -import com.android.gallery3d.app.Log; -import com.android.gallery3d.filtershow.filters.FiltersManager; -import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.FilterEnvironment; -import com.android.gallery3d.filtershow.presets.ImagePreset; - -public class RenderingRequest { - private static final String LOGTAG = "RenderingRequest"; - private boolean mIsDirect = false; - private Bitmap mBitmap = null; - private ImagePreset mImagePreset = null; - private ImagePreset mOriginalImagePreset = null; - private RenderingRequestCaller mCaller = null; - private float mScaleFactor = 1.0f; - private Rect mBounds = null; - private Rect mDestination = null; - private int mType = FULL_RENDERING; - public static final int FULL_RENDERING = 0; - public static final int FILTERS_RENDERING = 1; - public static final int GEOMETRY_RENDERING = 2; - public static final int ICON_RENDERING = 3; - public static final int PARTIAL_RENDERING = 4; - public static final int HIGHRES_RENDERING = 5; - public static final int STYLE_ICON_RENDERING = 6; - - private static final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888; - - public static void post(Bitmap source, ImagePreset preset, int type, RenderingRequestCaller caller) { - RenderingRequest.post(source, preset, type, caller, null, null); - } - - public static void post(Bitmap source, ImagePreset preset, int type, - RenderingRequestCaller caller, Rect bounds, Rect destination) { - if (((type != PARTIAL_RENDERING && type != HIGHRES_RENDERING) && source == null) - || preset == null || caller == null) { - Log.v(LOGTAG, "something null: source: " + source - + " or preset: " + preset + " or caller: " + caller); - return; - } - RenderingRequest request = new RenderingRequest(); - Bitmap bitmap = null; - if (type == FULL_RENDERING - || type == GEOMETRY_RENDERING - || type == ICON_RENDERING - || type == STYLE_ICON_RENDERING) { - CachingPipeline pipeline = new CachingPipeline( - FiltersManager.getManager(), "Icon"); - bitmap = pipeline.renderGeometryIcon(source, preset); - } else if (type != PARTIAL_RENDERING && type != HIGHRES_RENDERING) { - bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), mConfig); - } - - request.setBitmap(bitmap); - ImagePreset passedPreset = new ImagePreset(preset); - passedPreset.setImageLoader(MasterImage.getImage().getImageLoader()); - request.setOriginalImagePreset(preset); - request.setScaleFactor(MasterImage.getImage().getScaleFactor()); - - if (type == PARTIAL_RENDERING) { - request.setBounds(bounds); - request.setDestination(destination); - passedPreset.setPartialRendering(true, bounds); - } - - request.setImagePreset(passedPreset); - request.setType(type); - request.setCaller(caller); - request.post(); - } - - public void post() { - FilteringPipeline.getPipeline().postRenderingRequest(this); - } - - public void markAvailable() { - if (mBitmap == null || mImagePreset == null - || mCaller == null) { - return; - } - mCaller.available(this); - } - - public boolean isDirect() { - return mIsDirect; - } - - public void setDirect(boolean isDirect) { - mIsDirect = isDirect; - } - - public Bitmap getBitmap() { - return mBitmap; - } - - public void setBitmap(Bitmap bitmap) { - mBitmap = bitmap; - } - - public ImagePreset getImagePreset() { - return mImagePreset; - } - - public void setImagePreset(ImagePreset imagePreset) { - mImagePreset = imagePreset; - } - - public int getType() { - return mType; - } - - public void setType(int type) { - mType = type; - } - - public void setCaller(RenderingRequestCaller caller) { - mCaller = caller; - } - - public Rect getBounds() { - return mBounds; - } - - public void setBounds(Rect bounds) { - mBounds = bounds; - } - - public void setScaleFactor(float scaleFactor) { - mScaleFactor = scaleFactor; - } - - public float getScaleFactor() { - return mScaleFactor; - } - - public Rect getDestination() { - return mDestination; - } - - public void setDestination(Rect destination) { - mDestination = destination; - } - - public ImagePreset getOriginalImagePreset() { - return mOriginalImagePreset; - } - - public void setOriginalImagePreset(ImagePreset originalImagePreset) { - mOriginalImagePreset = originalImagePreset; - } -} diff --git a/src/com/android/gallery3d/filtershow/cache/RenderingRequestCaller.java b/src/com/android/gallery3d/filtershow/cache/RenderingRequestCaller.java deleted file mode 100644 index 240eb8f44..000000000 --- a/src/com/android/gallery3d/filtershow/cache/RenderingRequestCaller.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.cache; - -public interface RenderingRequestCaller { - public void available(RenderingRequest request); -} diff --git a/src/com/android/gallery3d/filtershow/category/Action.java b/src/com/android/gallery3d/filtershow/category/Action.java index b46147961..62bd99bc7 100644 --- a/src/com/android/gallery3d/filtershow/category/Action.java +++ b/src/com/android/gallery3d/filtershow/category/Action.java @@ -24,11 +24,11 @@ import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; -import com.android.gallery3d.filtershow.cache.RenderingRequest; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequest; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; public class Action implements RenderingRequestCaller { diff --git a/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java b/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java index 398c6785e..5baaeaf0f 100644 --- a/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java +++ b/src/com/android/gallery3d/filtershow/category/CategoryAdapter.java @@ -17,7 +17,6 @@ package com.android.gallery3d.filtershow.category; import android.content.Context; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -27,9 +26,7 @@ import android.widget.ListView; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation; -import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet; -import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.ui.FilterIconButton; public class CategoryAdapter extends ArrayAdapter { diff --git a/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java b/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java index 25169c2d8..fb9f95e97 100644 --- a/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java +++ b/src/com/android/gallery3d/filtershow/controller/BasicParameterStyle.java @@ -17,9 +17,8 @@ package com.android.gallery3d.filtershow.controller; import android.content.Context; -import android.util.Log; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; public class BasicParameterStyle implements ParameterStyles { protected String mParameterName; diff --git a/src/com/android/gallery3d/filtershow/controller/FilterView.java b/src/com/android/gallery3d/filtershow/controller/FilterView.java index 2be7f36a9..9ca81dc35 100644 --- a/src/com/android/gallery3d/filtershow/controller/FilterView.java +++ b/src/com/android/gallery3d/filtershow/controller/FilterView.java @@ -16,7 +16,7 @@ package com.android.gallery3d.filtershow.controller; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; public interface FilterView { public void computeIcon(int index, RenderingRequestCaller caller); diff --git a/src/com/android/gallery3d/filtershow/controller/ParameterStyles.java b/src/com/android/gallery3d/filtershow/controller/ParameterStyles.java index c267d3da3..7d250a0bf 100644 --- a/src/com/android/gallery3d/filtershow/controller/ParameterStyles.java +++ b/src/com/android/gallery3d/filtershow/controller/ParameterStyles.java @@ -18,7 +18,7 @@ package com.android.gallery3d.filtershow.controller; import android.content.Context; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; public interface ParameterStyles extends Parameter { public static String sParameterType = "ParameterStyles"; diff --git a/src/com/android/gallery3d/filtershow/controller/StyleChooser.java b/src/com/android/gallery3d/filtershow/controller/StyleChooser.java index b3d0de715..fb613abc7 100644 --- a/src/com/android/gallery3d/filtershow/controller/StyleChooser.java +++ b/src/com/android/gallery3d/filtershow/controller/StyleChooser.java @@ -11,8 +11,8 @@ import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.cache.RenderingRequest; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequest; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; import com.android.gallery3d.filtershow.editors.Editor; import java.util.Vector; diff --git a/src/com/android/gallery3d/filtershow/editors/Editor.java b/src/com/android/gallery3d/filtershow/editors/Editor.java index 789c728a2..7d395ef37 100644 --- a/src/com/android/gallery3d/filtershow/editors/Editor.java +++ b/src/com/android/gallery3d/filtershow/editors/Editor.java @@ -18,7 +18,6 @@ package com.android.gallery3d.filtershow.editors; import android.content.Context; import android.util.AttributeSet; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -37,7 +36,7 @@ import com.android.gallery3d.filtershow.controller.Control; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.imageshow.ImageShow; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; /** * Base class for Editors Must contain a mImageShow and a top level view diff --git a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java index daa599940..c0a6c139e 100644 --- a/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java +++ b/src/com/android/gallery3d/filtershow/filters/BaseFiltersManager.java @@ -20,7 +20,7 @@ import android.content.res.Resources; import android.util.Log; import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import java.util.HashMap; import java.util.Vector; diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java index 5ac87c665..05fdffbf7 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilter.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilter.java @@ -23,8 +23,8 @@ import android.support.v8.renderscript.Allocation; import android.widget.Toast; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; -import com.android.gallery3d.filtershow.presets.FilterEnvironment; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.FilterEnvironment; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; public abstract class ImageFilter implements Cloneable { private FilterEnvironment mEnvironment = null; diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java index 812ab02f0..2f1bbb0c7 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterDraw.java @@ -31,8 +31,7 @@ import android.graphics.PorterDuffColorFilter; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation.StrokeData; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.FilterEnvironment; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.FilterEnvironment; import java.util.Vector; diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java index 69d18f805..5695ef53e 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterRS.java @@ -22,7 +22,7 @@ import android.support.v8.renderscript.*; import android.util.Log; import android.content.res.Resources; import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.presets.PipelineInterface; +import com.android.gallery3d.filtershow.pipeline.PipelineInterface; public abstract class ImageFilterRS extends ImageFilter { private static final String LOGTAG = "ImageFilterRS"; diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java index f265c4dcc..6022ddac2 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterTinyPlanet.java @@ -18,14 +18,12 @@ package com.android.gallery3d.filtershow.filters; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; import android.graphics.RectF; import com.adobe.xmp.XMPException; import com.adobe.xmp.XMPMeta; import com.android.gallery3d.app.Log; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; /** * An image filter which creates a tiny planet projection. diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java index cfe135033..7e0a452bf 100644 --- a/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java +++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterVignette.java @@ -22,7 +22,7 @@ import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.presets.FilterEnvironment; +import com.android.gallery3d.filtershow.pipeline.FilterEnvironment; public class ImageFilterVignette extends SimpleImageFilter { private static final String LOGTAG = "ImageFilterVignette"; diff --git a/src/com/android/gallery3d/filtershow/history/HistoryItem.java b/src/com/android/gallery3d/filtershow/history/HistoryItem.java index ed550985d..92baef2ac 100644 --- a/src/com/android/gallery3d/filtershow/history/HistoryItem.java +++ b/src/com/android/gallery3d/filtershow/history/HistoryItem.java @@ -19,7 +19,7 @@ package com.android.gallery3d.filtershow.history; import android.graphics.Bitmap; import android.util.Log; import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; public class HistoryItem { private static final String LOGTAG = "HistoryItem"; diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java index 15609139b..58225c829 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java @@ -32,7 +32,7 @@ import android.view.View; import com.android.gallery3d.filtershow.history.HistoryItem; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata.FLIP; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; public abstract class ImageGeometry extends ImageShow { protected boolean mVisibilityGained = false; diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java index a95932d32..73a1ebf7d 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java +++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java @@ -39,7 +39,7 @@ import com.android.gallery3d.R; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.filters.ImageFilter; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import java.io.File; diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java index bc208887f..ffd69a662 100644 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java @@ -27,16 +27,16 @@ import android.os.Message; import com.android.gallery3d.filtershow.FilterShowActivity; import com.android.gallery3d.filtershow.history.HistoryManager; import com.android.gallery3d.filtershow.history.HistoryItem; -import com.android.gallery3d.filtershow.cache.FilteringPipeline; +import com.android.gallery3d.filtershow.pipeline.FilteringPipeline; import com.android.gallery3d.filtershow.cache.ImageLoader; -import com.android.gallery3d.filtershow.cache.RenderingRequest; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequest; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.filters.ImageFilter; import com.android.gallery3d.filtershow.pipeline.Buffer; import com.android.gallery3d.filtershow.pipeline.SharedBuffer; import com.android.gallery3d.filtershow.pipeline.SharedPreset; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.state.StateAdapter; import java.util.Vector; diff --git a/src/com/android/gallery3d/filtershow/pipeline/Buffer.java b/src/com/android/gallery3d/filtershow/pipeline/Buffer.java index c6dbdb75a..744451229 100644 --- a/src/com/android/gallery3d/filtershow/pipeline/Buffer.java +++ b/src/com/android/gallery3d/filtershow/pipeline/Buffer.java @@ -19,8 +19,6 @@ package com.android.gallery3d.filtershow.pipeline; import android.graphics.Bitmap; import android.support.v8.renderscript.Allocation; import android.support.v8.renderscript.RenderScript; -import com.android.gallery3d.filtershow.cache.CachingPipeline; -import com.android.gallery3d.filtershow.presets.ImagePreset; public class Buffer { private static final String LOGTAG = "Buffer"; diff --git a/src/com/android/gallery3d/filtershow/pipeline/CachingPipeline.java b/src/com/android/gallery3d/filtershow/pipeline/CachingPipeline.java new file mode 100644 index 000000000..88cf8ede2 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/CachingPipeline.java @@ -0,0 +1,459 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +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; +import android.util.Log; + +import com.android.gallery3d.filtershow.cache.ImageLoader; +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.MasterImage; + +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 volatile Allocation mOriginalAllocation = null; + private volatile Allocation mFiltersOnlyOriginalAllocation = null; + + protected volatile Allocation mInPixelsAllocation; + protected volatile Allocation mOutPixelsAllocation; + 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; + } + + 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() { + if (sRS != null) { + sRS.destroy(); + } + sRS = null; + sResources = null; + } + + public void stop() { + mEnvironment.setStop(true); + } + + 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; + mHighResPreviewScaleFactor = 1.0f; + + destroyPixelAllocations(); + } + } + + public Resources getResources() { + return sRS.getApplicationContext().getResources(); + } + + private synchronized void destroyPixelAllocations() { + if (DEBUG) { + Log.v(LOGTAG, "destroyPixelAllocations in " + getName()); + } + if (mInPixelsAllocation != null) { + mInPixelsAllocation.destroy(); + mInPixelsAllocation = null; + } + if (mOutPixelsAllocation != null) { + mOutPixelsAllocation.destroy(); + mOutPixelsAllocation = null; + } + mWidth = 0; + mHeight = 0; + } + + private String getType(RenderingRequest request) { + if (request.getType() == RenderingRequest.ICON_RENDERING) { + return "ICON_RENDERING"; + } + if (request.getType() == RenderingRequest.FILTERS_RENDERING) { + return "FILTERS_RENDERING"; + } + if (request.getType() == RenderingRequest.FULL_RENDERING) { + return "FULL_RENDERING"; + } + if (request.getType() == RenderingRequest.GEOMETRY_RENDERING) { + return "GEOMETRY_RENDERING"; + } + if (request.getType() == RenderingRequest.PARTIAL_RENDERING) { + return "PARTIAL_RENDERING"; + } + if (request.getType() == RenderingRequest.HIGHRES_RENDERING) { + return "HIGHRES_RENDERING"; + } + return "UNKNOWN TYPE!"; + } + + private void setupEnvironment(ImagePreset preset, boolean highResPreview) { + mEnvironment.setPipeline(this); + mEnvironment.setFiltersManager(mFiltersManager); + if (highResPreview) { + mEnvironment.setScaleFactor(mHighResPreviewScaleFactor); + } else { + mEnvironment.setScaleFactor(mPreviewScaleFactor); + } + mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); + mEnvironment.setImagePreset(preset); + mEnvironment.setStop(false); + } + + public void setOriginal(Bitmap bitmap) { + mOriginalBitmap = bitmap; + Log.v(LOGTAG,"setOriginal, size " + bitmap.getWidth() + " x " + bitmap.getHeight()); + ImagePreset preset = MasterImage.getImage().getPreset(); + setupEnvironment(preset, false); + updateOriginalAllocation(preset); + } + + private synchronized boolean updateOriginalAllocation(ImagePreset preset) { + Bitmap originalBitmap = mOriginalBitmap; + + if (originalBitmap == null) { + return false; + } + + GeometryMetadata geometry = preset.getGeometry(); + if (mPreviousGeometry != null && geometry.equals(mPreviousGeometry)) { + return false; + } + + if (DEBUG) { + Log.v(LOGTAG, "geometry has changed"); + } + + RenderScript RS = getRenderScriptContext(); + + Allocation filtersOnlyOriginalAllocation = mFiltersOnlyOriginalAllocation; + mFiltersOnlyOriginalAllocation = Allocation.createFromBitmap(RS, originalBitmap, + Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); + if (filtersOnlyOriginalAllocation != null) { + filtersOnlyOriginalAllocation.destroy(); + } + + Allocation originalAllocation = mOriginalAllocation; + mResizedOriginalBitmap = preset.applyGeometry(originalBitmap, mEnvironment); + mOriginalAllocation = Allocation.createFromBitmap(RS, mResizedOriginalBitmap, + Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); + if (originalAllocation != null) { + originalAllocation.destroy(); + } + + mPreviousGeometry = new GeometryMetadata(geometry); + return true; + } + + public synchronized void render(RenderingRequest request) { + synchronized (CachingPipeline.class) { + if (getRenderScriptContext() == null) { + return; + } + if (((request.getType() != RenderingRequest.PARTIAL_RENDERING + && request.getType() != RenderingRequest.HIGHRES_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, + request.getType() != RenderingRequest.HIGHRES_RENDERING); + 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)); + 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.HIGHRES_RENDERING) { + ImageLoader loader = MasterImage.getImage().getImageLoader(); + bitmap = loader.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) { + 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 + || request.getType() == RenderingRequest.HIGHRES_RENDERING + || request.getType() == RenderingRequest.STYLE_ICON_RENDERING) { + + if (request.getType() == RenderingRequest.ICON_RENDERING) { + mEnvironment.setQuality(FilterEnvironment.QUALITY_ICON); + } else { + mEnvironment.setQuality(FilterEnvironment.QUALITY_PREVIEW); + } + + Bitmap bmp = preset.apply(bitmap, mEnvironment); + if (!mEnvironment.needsStop()) { + request.setBitmap(bmp); + } + mFiltersManager.freeFilterResources(preset); + } + } + } + + 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); + boolean copyOut = false; + if (preset.nbFilters() > 0) { + copyOut = true; + } + preset.applyBorder(in, out, copyOut, mEnvironment); + } + } + + public synchronized Bitmap renderFinalImage(Bitmap bitmap, ImagePreset preset) { + synchronized (CachingPipeline.class) { + if (getRenderScriptContext() == null) { + return bitmap; + } + setupEnvironment(preset, false); + mEnvironment.setQuality(FilterEnvironment.QUALITY_FINAL); + mEnvironment.setScaleFactor(1.0f); + mFiltersManager.freeFilterResources(preset); + bitmap = preset.applyGeometry(bitmap, mEnvironment); + bitmap = preset.apply(bitmap, mEnvironment); + return bitmap; + } + } + + 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); + } + + 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 boolean needsRepaint() { + SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer(); + return buffer.checkRepaintNeeded(); + } + + public void setPreviewScaleFactor(float previewScaleFactor) { + mPreviewScaleFactor = previewScaleFactor; + } + + public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) { + mHighResPreviewScaleFactor = highResPreviewScaleFactor; + } + + public synchronized boolean isInitialized() { + return getRenderScriptContext() != null && mOriginalBitmap != null; + } + + public boolean prepareRenderscriptAllocations(Bitmap bitmap) { + RenderScript RS = getRenderScriptContext(); + boolean needsUpdate = false; + if (mOutPixelsAllocation == null || mInPixelsAllocation == null || + bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight) { + destroyPixelAllocations(); + Bitmap bitmapBuffer = bitmap; + if (bitmap.getConfig() == null || bitmap.getConfig() != BITMAP_CONFIG) { + bitmapBuffer = bitmap.copy(BITMAP_CONFIG, true); + } + mOutPixelsAllocation = Allocation.createFromBitmap(RS, bitmapBuffer, + Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); + mInPixelsAllocation = Allocation.createTyped(RS, + mOutPixelsAllocation.getType()); + needsUpdate = true; + } + if (RS != null) { + mInPixelsAllocation.copyFrom(bitmap); + } + if (bitmap.getWidth() != mWidth + || bitmap.getHeight() != mHeight) { + mWidth = bitmap.getWidth(); + mHeight = bitmap.getHeight(); + needsUpdate = true; + } + if (DEBUG) { + Log.v(LOGTAG, "prepareRenderscriptAllocations: " + needsUpdate + " in " + getName()); + } + return needsUpdate; + } + + public synchronized Allocation getInPixelsAllocation() { + return mInPixelsAllocation; + } + + public synchronized Allocation getOutPixelsAllocation() { + return mOutPixelsAllocation; + } + + public String getName() { + return mName; + } + + public RenderScript getRSContext() { + return CachingPipeline.getRenderScriptContext(); + } +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/FilterEnvironment.java b/src/com/android/gallery3d/filtershow/pipeline/FilterEnvironment.java new file mode 100644 index 000000000..f97dc757a --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/FilterEnvironment.java @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +import android.graphics.Bitmap; +import android.support.v8.renderscript.Allocation; + +import com.android.gallery3d.filtershow.filters.FilterRepresentation; +import com.android.gallery3d.filtershow.filters.FiltersManagerInterface; +import com.android.gallery3d.filtershow.filters.ImageFilter; + +import java.lang.ref.WeakReference; +import java.util.HashMap; + +public class FilterEnvironment { + private static final String LOGTAG = "FilterEnvironment"; + private ImagePreset mImagePreset; + private float mScaleFactor; + private int mQuality; + private FiltersManagerInterface mFiltersManager; + private PipelineInterface mPipeline; + private volatile boolean mStop = false; + + public static final int QUALITY_ICON = 0; + public static final int QUALITY_PREVIEW = 1; + public static final int QUALITY_FINAL = 2; + + public synchronized boolean needsStop() { + return mStop; + } + + public synchronized void setStop(boolean stop) { + this.mStop = stop; + } + + private HashMap> + bitmapCach = new HashMap>(); + + private HashMap + generalParameters = new HashMap(); + + public void cache(Buffer buffer) { + if (buffer == null) { + return; + } + Bitmap bitmap = buffer.getBitmap(); + if (bitmap == null) { + return; + } + Long key = calcKey(bitmap.getWidth(), bitmap.getHeight()); + bitmapCach.put(key, new WeakReference(bitmap)); + } + + public Bitmap getBitmap(int w, int h) { + Long key = calcKey(w, h); + WeakReference ref = bitmapCach.remove(key); + Bitmap bitmap = null; + if (ref != null) { + bitmap = ref.get(); + } + if (bitmap == null) { + bitmap = Bitmap.createBitmap( + w, h, Bitmap.Config.ARGB_8888); + } + return bitmap; + } + + private Long calcKey(long w, long h) { + return (w << 32) | (h << 32); + } + + public void setImagePreset(ImagePreset imagePreset) { + mImagePreset = imagePreset; + } + + public ImagePreset getImagePreset() { + return mImagePreset; + } + + public void setScaleFactor(float scaleFactor) { + mScaleFactor = scaleFactor; + } + + public float getScaleFactor() { + return mScaleFactor; + } + + public void setQuality(int quality) { + mQuality = quality; + } + + public int getQuality() { + return mQuality; + } + + public void setFiltersManager(FiltersManagerInterface filtersManager) { + mFiltersManager = filtersManager; + } + + public FiltersManagerInterface getFiltersManager() { + 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.setGeneralParameters(); + filter.setEnvironment(null); + } + + public Bitmap applyRepresentation(FilterRepresentation representation, Bitmap bitmap) { + ImageFilter filter = mFiltersManager.getFilterForRepresentation(representation); + filter.useRepresentation(representation); + filter.setEnvironment(this); + Bitmap ret = filter.apply(bitmap, mScaleFactor, mQuality); + filter.setGeneralParameters(); + filter.setEnvironment(null); + return ret; + } + + public PipelineInterface getPipeline() { + return mPipeline; + } + + public void setPipeline(PipelineInterface cachingPipeline) { + mPipeline = cachingPipeline; + } + + public synchronized void clearGeneralParameters() { + generalParameters = null; + } + + public synchronized Integer getGeneralParameter(int id) { + if (generalParameters == null || !generalParameters.containsKey(id)) { + return null; + } + return generalParameters.get(id); + } + + public synchronized void setGeneralParameter(int id, int value) { + if (generalParameters == null) { + generalParameters = new HashMap(); + } + + generalParameters.put(id, value); + } + +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java b/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java new file mode 100644 index 000000000..1fec62197 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/FilteringPipeline.java @@ -0,0 +1,240 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +import android.graphics.Bitmap; +import android.os.*; +import android.os.Process; +import android.util.Log; + +import com.android.gallery3d.filtershow.cache.ImageLoader; +import com.android.gallery3d.filtershow.filters.FiltersManager; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +public class FilteringPipeline implements Handler.Callback { + + private static volatile FilteringPipeline sPipeline = null; + private static final String LOGTAG = "FilteringPipeline"; + private boolean DEBUG = false; + + private static long HIRES_DELAY = 300; // in ms + + private volatile boolean mPipelineIsOn = false; + + private CachingPipeline mAccessoryPipeline = null; + private CachingPipeline mPreviewPipeline = null; + private CachingPipeline mHighresPreviewPipeline = null; + + private HandlerThread mHandlerThread = null; + private final static int NEW_PRESET = 0; + private final static int NEW_RENDERING_REQUEST = 1; + private final static int COMPUTE_PRESET = 2; + private final static int COMPUTE_RENDERING_REQUEST = 3; + private final static int COMPUTE_PARTIAL_RENDERING_REQUEST = 4; + private final static int COMPUTE_HIGHRES_RENDERING_REQUEST = 5; + + private volatile boolean mHasUnhandledPreviewRequest = false; + + private String getType(int value) { + if (value == COMPUTE_RENDERING_REQUEST) { + return "COMPUTE_RENDERING_REQUEST"; + } + if (value == COMPUTE_PARTIAL_RENDERING_REQUEST) { + return "COMPUTE_PARTIAL_RENDERING_REQUEST"; + } + if (value == COMPUTE_HIGHRES_RENDERING_REQUEST) { + return "COMPUTE_HIGHRES_RENDERING_REQUEST"; + } + return "UNKNOWN TYPE"; + } + + private Handler mProcessingHandler = null; + private final Handler mUIHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case NEW_PRESET: { + MasterImage.getImage().notifyObservers(); + if (mHasUnhandledPreviewRequest) { + updatePreviewBuffer(); + } + break; + } + case NEW_RENDERING_REQUEST: { + RenderingRequest request = (RenderingRequest) msg.obj; + request.markAvailable(); + break; + } + } + } + }; + + @Override + public boolean handleMessage(Message msg) { + if (!mPipelineIsOn) { + return false; + } + switch (msg.what) { + case COMPUTE_PRESET: { + SharedBuffer buffer = MasterImage.getImage().getPreviewBuffer(); + SharedPreset preset = MasterImage.getImage().getPreviewPreset(); + ImagePreset renderingPreset = preset.dequeuePreset(); + if (renderingPreset != null) { + mPreviewPipeline.compute(buffer, renderingPreset, COMPUTE_PRESET); + // set the preset we used in the buffer for later inspection UI-side + buffer.getProducer().setPreset(renderingPreset); + buffer.getProducer().sync(); + buffer.swapProducer(); // push back the result + Message uimsg = mUIHandler.obtainMessage(NEW_PRESET); + mUIHandler.sendMessage(uimsg); + } + break; + } + case COMPUTE_RENDERING_REQUEST: + case COMPUTE_PARTIAL_RENDERING_REQUEST: + case COMPUTE_HIGHRES_RENDERING_REQUEST: { + + if (DEBUG) { + Log.v(LOGTAG, "Compute Request: " + getType(msg.what)); + } + + RenderingRequest request = (RenderingRequest) msg.obj; + if (msg.what == COMPUTE_HIGHRES_RENDERING_REQUEST) { + mHighresPreviewPipeline.render(request); + } else { + mAccessoryPipeline.render(request); + } + if (request.getBitmap() != null) { + Message uimsg = mUIHandler.obtainMessage(NEW_RENDERING_REQUEST); + uimsg.obj = request; + mUIHandler.sendMessage(uimsg); + } + break; + } + } + return false; + } + + private FilteringPipeline() { + mHandlerThread = new HandlerThread("FilteringPipeline", + Process.THREAD_PRIORITY_FOREGROUND); + mHandlerThread.start(); + mProcessingHandler = new Handler(mHandlerThread.getLooper(), this); + mAccessoryPipeline = new CachingPipeline( + FiltersManager.getManager(), "Accessory"); + mPreviewPipeline = new CachingPipeline( + FiltersManager.getPreviewManager(), "Preview"); + mHighresPreviewPipeline = new CachingPipeline( + FiltersManager.getHighresManager(), "Highres"); + } + + public synchronized static FilteringPipeline getPipeline() { + if (sPipeline == null) { + sPipeline = new FilteringPipeline(); + } + return sPipeline; + } + + public void setOriginal(Bitmap bitmap) { + if (mPipelineIsOn) { + Log.e(LOGTAG, "setOriginal called after pipeline initialization!"); + return; + } + mAccessoryPipeline.setOriginal(bitmap); + mPreviewPipeline.setOriginal(bitmap); + mHighresPreviewPipeline.setOriginal(bitmap); + } + + public void postRenderingRequest(RenderingRequest request) { + if (!mPipelineIsOn) { + return; + } + int type = COMPUTE_RENDERING_REQUEST; + if (request.getType() == RenderingRequest.PARTIAL_RENDERING) { + type = COMPUTE_PARTIAL_RENDERING_REQUEST; + } + if (request.getType() == RenderingRequest.HIGHRES_RENDERING) { + type = COMPUTE_HIGHRES_RENDERING_REQUEST; + ImageLoader imageLoader = MasterImage.getImage().getImageLoader(); + if (imageLoader.getOriginalBitmapHighres() == null) { + return; + } + } + Message msg = mProcessingHandler.obtainMessage(type); + msg.obj = request; + if (type == COMPUTE_PARTIAL_RENDERING_REQUEST + || type == COMPUTE_HIGHRES_RENDERING_REQUEST) { + if (mProcessingHandler.hasMessages(msg.what)) { + mProcessingHandler.removeMessages(msg.what); + } + mProcessingHandler.sendMessageDelayed(msg, HIRES_DELAY); + } else { + mProcessingHandler.sendMessage(msg); + } + } + + public void updatePreviewBuffer() { + if (!mPipelineIsOn) { + return; + } + mHasUnhandledPreviewRequest = true; + mHighresPreviewPipeline.stop(); + if (mProcessingHandler.hasMessages(COMPUTE_PRESET)) { + return; + } + if (!mPreviewPipeline.needsRepaint()) { + return; + } + if (MasterImage.getImage().getPreset() == null) { + return; + } + Message msg = mProcessingHandler.obtainMessage(COMPUTE_PRESET); + msg.obj = MasterImage.getImage().getPreset(); + mHasUnhandledPreviewRequest = false; + mProcessingHandler.sendMessageAtFrontOfQueue(msg); + } + + public void setPreviewScaleFactor(float previewScaleFactor) { + mAccessoryPipeline.setPreviewScaleFactor(previewScaleFactor); + mPreviewPipeline.setPreviewScaleFactor(previewScaleFactor); + mHighresPreviewPipeline.setPreviewScaleFactor(previewScaleFactor); + } + + public void setHighResPreviewScaleFactor(float highResPreviewScaleFactor) { + mAccessoryPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor); + mPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor); + mHighresPreviewPipeline.setHighResPreviewScaleFactor(highResPreviewScaleFactor); + } + + public static synchronized void reset() { + sPipeline.mAccessoryPipeline.reset(); + sPipeline.mPreviewPipeline.reset(); + sPipeline.mHighresPreviewPipeline.reset(); + sPipeline.mHandlerThread.quit(); + sPipeline = null; + } + + public void turnOnPipeline(boolean t) { + mPipelineIsOn = t; + if (mPipelineIsOn) { + assert(mPreviewPipeline.isInitialized()); + assert(mAccessoryPipeline.isInitialized()); + assert(mHighresPreviewPipeline.isInitialized()); + updatePreviewBuffer(); + } + } +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java new file mode 100644 index 000000000..c78bc1ef4 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java @@ -0,0 +1,700 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.support.v8.renderscript.Allocation; +import android.util.JsonReader; +import android.util.JsonWriter; +import android.util.Log; + +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.cache.ImageLoader; +import com.android.gallery3d.filtershow.filters.BaseFiltersManager; +import com.android.gallery3d.filtershow.filters.FilterFxRepresentation; +import com.android.gallery3d.filtershow.filters.FilterImageBorderRepresentation; +import com.android.gallery3d.filtershow.filters.FilterRepresentation; +import com.android.gallery3d.filtershow.filters.FiltersManager; +import com.android.gallery3d.filtershow.filters.ImageFilter; +import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; +import com.android.gallery3d.filtershow.imageshow.MasterImage; +import com.android.gallery3d.filtershow.state.State; +import com.android.gallery3d.filtershow.state.StateAdapter; +import com.android.gallery3d.util.UsageStatistics; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.Vector; + +public class ImagePreset { + + private static final String LOGTAG = "ImagePreset"; + + private ImageLoader mImageLoader = null; + + private Vector mFilters = new Vector(); + + protected boolean mIsFxPreset = false; + + private boolean mDoApplyGeometry = true; + private boolean mDoApplyFilters = true; + + private boolean mPartialRendering = false; + private Rect mPartialRenderingBounds; + private static final boolean DEBUG = true; + + public ImagePreset() { + } + + public ImagePreset(ImagePreset source) { + try { + for (int i = 0; i < source.mFilters.size(); i++) { + FilterRepresentation representation = null; + FilterRepresentation sourceRepresentation = source.mFilters.elementAt(i); + if (sourceRepresentation instanceof GeometryMetadata) { + GeometryMetadata geoData = new GeometryMetadata(); + GeometryMetadata srcGeo = (GeometryMetadata) sourceRepresentation; + geoData.set(srcGeo); + representation = geoData; + } else { + // TODO: get rid of clone()... + representation = sourceRepresentation.clone(); + } + addFilter(representation); + } + } catch (java.lang.CloneNotSupportedException e) { + Log.v(LOGTAG, "Exception trying to clone: " + e); + } + mImageLoader = source.getImageLoader(); + } + + public FilterRepresentation getFilterRepresentation(int position) { + FilterRepresentation representation = null; + try { + representation = mFilters.elementAt(position).clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + return representation; + } + + public int getPositionForRepresentation(FilterRepresentation representation) { + for (int i = 0; i < mFilters.size(); i++) { + if (mFilters.elementAt(i).getFilterClass() == representation.getFilterClass()) { + return i; + } + } + return -1; + } + + private FilterRepresentation getFilterRepresentationForType(int type) { + for (int i = 0; i < mFilters.size(); i++) { + if (mFilters.elementAt(i).getFilterType() == type) { + return mFilters.elementAt(i); + } + } + return null; + } + + public int getPositionForType(int type) { + for (int i = 0; i < mFilters.size(); i++) { + if (mFilters.elementAt(i).getFilterType() == type) { + return i; + } + } + return -1; + } + + public FilterRepresentation getFilterRepresentationCopyFrom(FilterRepresentation filterRepresentation) { + // TODO: add concept of position in the filters (to allow multiple instances) + if (filterRepresentation == null) { + return null; + } + int position = getPositionForRepresentation(filterRepresentation); + if (position == -1) { + return null; + } + FilterRepresentation representation = mFilters.elementAt(position); + if (representation != null) { + try { + representation = representation.clone(); + } catch (CloneNotSupportedException e) { + e.printStackTrace(); + } + } + return representation; + } + + public void updateFilterRepresentation(FilterRepresentation representation) { + if (representation == null) { + return; + } + if (representation instanceof GeometryMetadata) { + setGeometry((GeometryMetadata) representation); + } else { + int position = getPositionForRepresentation(representation); + if (position == -1) { + return; + } + FilterRepresentation old = mFilters.elementAt(position); + old.useParametersFrom(representation); + } + MasterImage.getImage().invalidatePreview(); + fillImageStateAdapter(MasterImage.getImage().getState()); + } + + public void setDoApplyGeometry(boolean value) { + mDoApplyGeometry = value; + } + + public void setDoApplyFilters(boolean value) { + mDoApplyFilters = value; + } + + public boolean getDoApplyFilters() { + return mDoApplyFilters; + } + + public GeometryMetadata getGeometry() { + for (FilterRepresentation representation : mFilters) { + if (representation instanceof GeometryMetadata) { + return (GeometryMetadata) representation; + } + } + GeometryMetadata geo = new GeometryMetadata(); + mFilters.add(0, geo); // Hard Requirement for now -- Geometry ought to be first. + return geo; + } + + public boolean hasModifications() { + for (int i = 0; i < mFilters.size(); i++) { + FilterRepresentation filter = mFilters.elementAt(i); + if (filter instanceof GeometryMetadata) { + if (((GeometryMetadata) filter).hasModifications()) { + return true; + } + } else if (!filter.isNil()) { + return true; + } + } + return false; + } + + public boolean isPanoramaSafe() { + for (FilterRepresentation representation : mFilters) { + if (representation instanceof GeometryMetadata) { + if (((GeometryMetadata) representation).hasModifications()) { + return false; + } + } + if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER + && !representation.isNil()) { + return false; + } + if (representation.getFilterType() == FilterRepresentation.TYPE_VIGNETTE + && !representation.isNil()) { + return false; + } + if (representation.getFilterType() == FilterRepresentation.TYPE_TINYPLANET + && !representation.isNil()) { + return false; + } + } + return true; + } + + public void setGeometry(GeometryMetadata representation) { + GeometryMetadata geoData = getGeometry(); + if (geoData != representation) { + geoData.set(representation); + } + } + + public ImageLoader getImageLoader() { + return mImageLoader; + } + + public void setImageLoader(ImageLoader mImageLoader) { + this.mImageLoader = mImageLoader; + } + + public boolean equals(ImagePreset preset) { + if (!same(preset)) { + return false; + } + if (mDoApplyFilters && preset.mDoApplyFilters) { + for (int i = 0; i < preset.mFilters.size(); i++) { + FilterRepresentation a = preset.mFilters.elementAt(i); + FilterRepresentation b = mFilters.elementAt(i); + if (!a.equals(b)) { + return false; + } + } + } + return true; + } + + public boolean same(ImagePreset preset) { + if (preset == null) { + return false; + } + + if (preset.mFilters.size() != mFilters.size()) { + return false; + } + + if (mDoApplyGeometry != preset.mDoApplyGeometry) { + return false; + } + + if (mDoApplyGeometry && !getGeometry().equals(preset.getGeometry())) { + return false; + } + + if (mDoApplyFilters != preset.mDoApplyFilters) { + if (mFilters.size() > 0 || preset.mFilters.size() > 0) { + return false; + } + } + + if (mDoApplyFilters && preset.mDoApplyFilters) { + for (int i = 0; i < preset.mFilters.size(); i++) { + FilterRepresentation a = preset.mFilters.elementAt(i); + FilterRepresentation b = mFilters.elementAt(i); + if (a instanceof GeometryMetadata) { + // Note: Geometry will always be at the same place + continue; + } + if (!a.same(b)) { + return false; + } + } + } + + return true; + } + + public int similarUpTo(ImagePreset preset) { + if (!getGeometry().equals(preset.getGeometry())) { + return -1; + } + + for (int i = 0; i < preset.mFilters.size(); i++) { + FilterRepresentation a = preset.mFilters.elementAt(i); + if (i < mFilters.size()) { + FilterRepresentation b = mFilters.elementAt(i); + if (!a.same(b)) { + return i; + } + if (!a.equals(b)) { + return i; + } + } else { + return i; + } + } + return preset.mFilters.size(); + } + + public void showFilters() { + Log.v(LOGTAG, "\\\\\\ showFilters -- " + mFilters.size() + " filters"); + int n = 0; + for (FilterRepresentation representation : mFilters) { + Log.v(LOGTAG, " filter " + n + " : " + representation.toString()); + n++; + } + Log.v(LOGTAG, "/// showFilters -- " + mFilters.size() + " filters"); + } + + public FilterRepresentation getLastRepresentation() { + if (mFilters.size() > 0) { + return mFilters.lastElement(); + } + return null; + } + + public void removeFilter(FilterRepresentation filterRepresentation) { + if (filterRepresentation.getFilterType() == FilterRepresentation.TYPE_BORDER) { + for (int i = 0; i < mFilters.size();i++) { + if (mFilters.elementAt(i).getFilterType() + == filterRepresentation.getFilterType()) { + mFilters.remove(i); + break; + } + } + } else { + for (int i = 0; i < mFilters.size(); i++) { + if (mFilters.elementAt(i).getFilterClass() + == filterRepresentation.getFilterClass()) { + mFilters.remove(i); + break; + } + } + } + } + + // If the filter is an "None" effect or border, then just don't add this + // filter. + public void addFilter(FilterRepresentation representation) { + if (representation instanceof GeometryMetadata) { + setGeometry((GeometryMetadata) representation); + return; + } + + if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { + removeFilter(representation); + if (!isNoneBorderFilter(representation)) { + mFilters.add(representation); + } + } else if (representation.getFilterType() == FilterRepresentation.TYPE_FX) { + boolean found = false; + for (int i = 0; i < mFilters.size(); i++) { + int type = mFilters.elementAt(i).getFilterType(); + if (found) { + if (type != FilterRepresentation.TYPE_VIGNETTE) { + mFilters.remove(i); + continue; + } + } + if (type == FilterRepresentation.TYPE_FX) { + mFilters.remove(i); + if (!isNoneFxFilter(representation)) { + mFilters.add(i, representation); + } + found = true; + } + } + if (!found) { + if (!isNoneFxFilter(representation)) { + mFilters.add(representation); + } + } + } else { + mFilters.add(representation); + } + } + + private boolean isNoneBorderFilter(FilterRepresentation representation) { + return representation instanceof FilterImageBorderRepresentation && + ((FilterImageBorderRepresentation) representation).getDrawableResource() == 0; + } + + private boolean isNoneFxFilter(FilterRepresentation representation) { + return representation instanceof FilterFxRepresentation && + ((FilterFxRepresentation)representation).getNameResource() == R.string.none; + } + + public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) { + for (int i = 0; i < mFilters.size(); i++) { + FilterRepresentation representation = mFilters.elementAt(i); + if (representation.getFilterClass() == filterRepresentation.getFilterClass()) { + return representation; + } + } + return null; + } + + public Bitmap apply(Bitmap original, FilterEnvironment environment) { + Bitmap bitmap = original; + bitmap = applyFilters(bitmap, -1, -1, environment); + return applyBorder(bitmap, environment); + } + + public Bitmap applyGeometry(Bitmap bitmap, FilterEnvironment environment) { + // Apply any transform -- 90 rotate, flip, straighten, crop + // Returns a new bitmap. + if (mDoApplyGeometry) { + GeometryMetadata geoData = getGeometry(); + bitmap = environment.applyRepresentation(geoData, bitmap); + } + return bitmap; + } + + public Bitmap applyBorder(Bitmap bitmap, FilterEnvironment environment) { + // get the border from the list of filters. + FilterRepresentation border = getFilterRepresentationForType( + FilterRepresentation.TYPE_BORDER); + if (border != null && mDoApplyGeometry) { + bitmap = environment.applyRepresentation(border, bitmap); + if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { + UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, + "SaveBorder", border.getSerializationName(), 1); + } + } + return bitmap; + } + + public int nbFilters() { + return mFilters.size(); + } + + public Bitmap applyFilters(Bitmap bitmap, int from, int to, FilterEnvironment environment) { + if (mDoApplyFilters) { + if (from < 0) { + from = 0; + } + if (to == -1) { + to = mFilters.size(); + } + if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { + UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, + "SaveFilters", "Total", to - from + 1); + } + for (int i = from; i < to; i++) { + FilterRepresentation representation = mFilters.elementAt(i); + if (representation instanceof GeometryMetadata) { + // skip the geometry as it's already applied. + continue; + } + if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { + // for now, let's skip the border as it will be applied in applyBorder() + // TODO: might be worth getting rid of applyBorder. + continue; + } + bitmap = environment.applyRepresentation(representation, bitmap); + if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { + UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, + "SaveFilter", representation.getSerializationName(), 1); + } + if (environment.needsStop()) { + return bitmap; + } + } + } + + return bitmap; + } + + public void applyBorder(Allocation in, Allocation out, + boolean copyOut, FilterEnvironment environment) { + FilterRepresentation border = getFilterRepresentationForType( + FilterRepresentation.TYPE_BORDER); + if (border != null && mDoApplyGeometry) { + // TODO: should keep the bitmap around + Allocation bitmapIn = in; + if (copyOut) { + bitmapIn = Allocation.createTyped( + CachingPipeline.getRenderScriptContext(), in.getType()); + bitmapIn.copyFrom(out); + } + environment.applyRepresentation(border, bitmapIn, out); + } + } + + 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 = mFilters.elementAt(i); + if (representation instanceof GeometryMetadata) { + // skip the geometry as it's already applied. + continue; + } + if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { + // for now, let's skip the border as it will be applied in applyBorder() + continue; + } + if (i > from) { + in.copyFrom(out); + } + environment.applyRepresentation(representation, in, out); + } + } + } + + public boolean canDoPartialRendering() { + if (ImageLoader.getZoomOrientation() != ImageLoader.ORI_NORMAL) { + return false; + } + for (int i = 0; i < mFilters.size(); i++) { + FilterRepresentation representation = mFilters.elementAt(i); + if (representation instanceof GeometryMetadata + && ((GeometryMetadata) representation).hasModifications()) { + return false; + } + if (!representation.supportsPartialRendering()) { + return false; + } + } + return true; + } + + public void fillImageStateAdapter(StateAdapter imageStateAdapter) { + if (imageStateAdapter == null) { + return; + } + Vector states = new Vector(); + for (FilterRepresentation filter : mFilters) { + if (filter instanceof GeometryMetadata) { + // TODO: supports Geometry representations in the state panel. + continue; + } + State state = new State(filter.getName()); + state.setFilterRepresentation(filter); + states.add(state); + } + imageStateAdapter.fill(states); + } + + public void setPartialRendering(boolean partialRendering, Rect bounds) { + mPartialRendering = partialRendering; + mPartialRenderingBounds = bounds; + } + + public boolean isPartialRendering() { + return mPartialRendering; + } + + public Rect getPartialRenderingBounds() { + return mPartialRenderingBounds; + } + + public Vector getUsedFilters(BaseFiltersManager filtersManager) { + Vector usedFilters = new Vector(); + for (int i = 0; i < mFilters.size(); i++) { + FilterRepresentation representation = mFilters.elementAt(i); + ImageFilter filter = filtersManager.getFilterForRepresentation(representation); + usedFilters.add(filter); + } + return usedFilters; + } + + public String getJsonString(String name) { + StringWriter swriter = new StringWriter(); + try { + JsonWriter writer = new JsonWriter(swriter); + writeJson(writer, name); + writer.close(); + } catch (IOException e) { + return null; + } + return swriter.toString(); + } + + public void writeJson(JsonWriter writer, String name) { + int numFilters = mFilters.size(); + try { + writer.beginObject(); + GeometryMetadata geoData = getGeometry(); + writer.name(geoData.getSerializationName()); + writer.beginObject(); + { + String[][] rep = geoData.serializeRepresentation(); + for (int i = 0; i < rep.length; i++) { + writer.name(rep[i][0]); + writer.value(rep[i][1]); + } + } + writer.endObject(); + + for (int i = 0; i < numFilters; i++) { + FilterRepresentation filter = mFilters.get(i); + if (filter instanceof GeometryMetadata) { + continue; + } + String sname = filter.getSerializationName(); + if (DEBUG) { + Log.v(LOGTAG, "Serialization: " + sname); + if (sname == null) { + Log.v(LOGTAG, "Serialization: " + filter); + } + } + writer.name(sname); + filter.serializeRepresentation(writer); + } + writer.endObject(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * populates preset from JSON string + * @param filterString a JSON string + * @return true on success if false ImagePreset is undefined + */ + public boolean readJsonFromString(String filterString) { + if (DEBUG) { + Log.v(LOGTAG,"reading preset: \""+filterString+"\""); + } + StringReader sreader = new StringReader(filterString); + try { + JsonReader reader = new JsonReader(sreader); + boolean ok = readJson(reader); + if (!ok) { + reader.close(); + return false; + } + reader.close(); + } catch (Exception e) { + Log.e(LOGTAG,"parsing the filter parameters:",e); + return false; + } + return true; + } + + /** + * populates preset from JSON stream + * @param sreader a JSON string + * @return true on success if false ImagePreset is undefined + */ + public boolean readJson(JsonReader sreader) throws IOException { + sreader.beginObject(); + + while (sreader.hasNext()) { + String name = sreader.nextName(); + FilterRepresentation filter = creatFilterFromName(name); + if (filter == null) { + Log.w(LOGTAG,"UNKNOWN FILTER! "+name); + return false; + } + filter.deSerializeRepresentation(sreader); + addFilter(filter); + } + sreader.endObject(); + return true; + } + + FilterRepresentation creatFilterFromName(String name) { + if (GeometryMetadata.SERIALIZATION_NAME.equalsIgnoreCase(name)) { + return new GeometryMetadata(); + } + FiltersManager filtersManager = FiltersManager.getManager(); + return filtersManager.createFilterFromName(name); + } + + public void updateWith(ImagePreset preset) { + if (preset.mFilters.size() != mFilters.size()) { + Log.e(LOGTAG, "Updating a preset with an incompatible one"); + return; + } + for (int i = 0; i < mFilters.size(); i++) { + FilterRepresentation destRepresentation = mFilters.elementAt(i); + FilterRepresentation sourceRepresentation = preset.mFilters.elementAt(i); + destRepresentation.useParametersFrom(sourceRepresentation); + } + } +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/PipelineInterface.java b/src/com/android/gallery3d/filtershow/pipeline/PipelineInterface.java new file mode 100644 index 000000000..d53768c95 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/PipelineInterface.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.support.v8.renderscript.Allocation; +import android.support.v8.renderscript.RenderScript; + +public interface PipelineInterface { + public String getName(); + public Resources getResources(); + public Allocation getInPixelsAllocation(); + public Allocation getOutPixelsAllocation(); + public boolean prepareRenderscriptAllocations(Bitmap bitmap); + public RenderScript getRSContext(); +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/RenderingRequest.java b/src/com/android/gallery3d/filtershow/pipeline/RenderingRequest.java new file mode 100644 index 000000000..8306f388c --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/RenderingRequest.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +import android.graphics.Bitmap; +import android.graphics.Rect; +import com.android.gallery3d.app.Log; +import com.android.gallery3d.filtershow.filters.FiltersManager; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +public class RenderingRequest { + private static final String LOGTAG = "RenderingRequest"; + private boolean mIsDirect = false; + private Bitmap mBitmap = null; + private ImagePreset mImagePreset = null; + private ImagePreset mOriginalImagePreset = null; + private RenderingRequestCaller mCaller = null; + private float mScaleFactor = 1.0f; + private Rect mBounds = null; + private Rect mDestination = null; + private int mType = FULL_RENDERING; + public static final int FULL_RENDERING = 0; + public static final int FILTERS_RENDERING = 1; + public static final int GEOMETRY_RENDERING = 2; + public static final int ICON_RENDERING = 3; + public static final int PARTIAL_RENDERING = 4; + public static final int HIGHRES_RENDERING = 5; + public static final int STYLE_ICON_RENDERING = 6; + + private static final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888; + + public static void post(Bitmap source, ImagePreset preset, int type, RenderingRequestCaller caller) { + RenderingRequest.post(source, preset, type, caller, null, null); + } + + public static void post(Bitmap source, ImagePreset preset, int type, + RenderingRequestCaller caller, Rect bounds, Rect destination) { + if (((type != PARTIAL_RENDERING && type != HIGHRES_RENDERING) && source == null) + || preset == null || caller == null) { + Log.v(LOGTAG, "something null: source: " + source + + " or preset: " + preset + " or caller: " + caller); + return; + } + RenderingRequest request = new RenderingRequest(); + Bitmap bitmap = null; + if (type == FULL_RENDERING + || type == GEOMETRY_RENDERING + || type == ICON_RENDERING + || type == STYLE_ICON_RENDERING) { + CachingPipeline pipeline = new CachingPipeline( + FiltersManager.getManager(), "Icon"); + bitmap = pipeline.renderGeometryIcon(source, preset); + } else if (type != PARTIAL_RENDERING && type != HIGHRES_RENDERING) { + bitmap = Bitmap.createBitmap(source.getWidth(), source.getHeight(), mConfig); + } + + request.setBitmap(bitmap); + ImagePreset passedPreset = new ImagePreset(preset); + passedPreset.setImageLoader(MasterImage.getImage().getImageLoader()); + request.setOriginalImagePreset(preset); + request.setScaleFactor(MasterImage.getImage().getScaleFactor()); + + if (type == PARTIAL_RENDERING) { + request.setBounds(bounds); + request.setDestination(destination); + passedPreset.setPartialRendering(true, bounds); + } + + request.setImagePreset(passedPreset); + request.setType(type); + request.setCaller(caller); + request.post(); + } + + public void post() { + FilteringPipeline.getPipeline().postRenderingRequest(this); + } + + public void markAvailable() { + if (mBitmap == null || mImagePreset == null + || mCaller == null) { + return; + } + mCaller.available(this); + } + + public boolean isDirect() { + return mIsDirect; + } + + public void setDirect(boolean isDirect) { + mIsDirect = isDirect; + } + + public Bitmap getBitmap() { + return mBitmap; + } + + public void setBitmap(Bitmap bitmap) { + mBitmap = bitmap; + } + + public ImagePreset getImagePreset() { + return mImagePreset; + } + + public void setImagePreset(ImagePreset imagePreset) { + mImagePreset = imagePreset; + } + + public int getType() { + return mType; + } + + public void setType(int type) { + mType = type; + } + + public void setCaller(RenderingRequestCaller caller) { + mCaller = caller; + } + + public Rect getBounds() { + return mBounds; + } + + public void setBounds(Rect bounds) { + mBounds = bounds; + } + + public void setScaleFactor(float scaleFactor) { + mScaleFactor = scaleFactor; + } + + public float getScaleFactor() { + return mScaleFactor; + } + + public Rect getDestination() { + return mDestination; + } + + public void setDestination(Rect destination) { + mDestination = destination; + } + + public ImagePreset getOriginalImagePreset() { + return mOriginalImagePreset; + } + + public void setOriginalImagePreset(ImagePreset originalImagePreset) { + mOriginalImagePreset = originalImagePreset; + } +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/RenderingRequestCaller.java b/src/com/android/gallery3d/filtershow/pipeline/RenderingRequestCaller.java new file mode 100644 index 000000000..b978e7040 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/pipeline/RenderingRequestCaller.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.filtershow.pipeline; + +public interface RenderingRequestCaller { + public void available(RenderingRequest request); +} diff --git a/src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java b/src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java index e87469458..3f850fed2 100644 --- a/src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java +++ b/src/com/android/gallery3d/filtershow/pipeline/SharedPreset.java @@ -16,8 +16,6 @@ package com.android.gallery3d.filtershow.pipeline; -import com.android.gallery3d.filtershow.presets.ImagePreset; - public class SharedPreset { private volatile ImagePreset mProducerPreset = null; diff --git a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java b/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java deleted file mode 100644 index 6a130a3e3..000000000 --- a/src/com/android/gallery3d/filtershow/presets/FilterEnvironment.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.presets; - -import android.graphics.Bitmap; -import android.support.v8.renderscript.Allocation; - -import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.filters.FiltersManagerInterface; -import com.android.gallery3d.filtershow.filters.ImageFilter; -import com.android.gallery3d.filtershow.pipeline.Buffer; - -import java.lang.ref.WeakReference; -import java.util.HashMap; - -public class FilterEnvironment { - private static final String LOGTAG = "FilterEnvironment"; - private ImagePreset mImagePreset; - private float mScaleFactor; - private int mQuality; - private FiltersManagerInterface mFiltersManager; - private PipelineInterface mPipeline; - private volatile boolean mStop = false; - - public static final int QUALITY_ICON = 0; - public static final int QUALITY_PREVIEW = 1; - public static final int QUALITY_FINAL = 2; - - public synchronized boolean needsStop() { - return mStop; - } - - public synchronized void setStop(boolean stop) { - this.mStop = stop; - } - - private HashMap> - bitmapCach = new HashMap>(); - - private HashMap - generalParameters = new HashMap(); - - public void cache(Buffer buffer) { - if (buffer == null) { - return; - } - Bitmap bitmap = buffer.getBitmap(); - if (bitmap == null) { - return; - } - Long key = calcKey(bitmap.getWidth(), bitmap.getHeight()); - bitmapCach.put(key, new WeakReference(bitmap)); - } - - public Bitmap getBitmap(int w, int h) { - Long key = calcKey(w, h); - WeakReference ref = bitmapCach.remove(key); - Bitmap bitmap = null; - if (ref != null) { - bitmap = ref.get(); - } - if (bitmap == null) { - bitmap = Bitmap.createBitmap( - w, h, Bitmap.Config.ARGB_8888); - } - return bitmap; - } - - private Long calcKey(long w, long h) { - return (w << 32) | (h << 32); - } - - public void setImagePreset(ImagePreset imagePreset) { - mImagePreset = imagePreset; - } - - public ImagePreset getImagePreset() { - return mImagePreset; - } - - public void setScaleFactor(float scaleFactor) { - mScaleFactor = scaleFactor; - } - - public float getScaleFactor() { - return mScaleFactor; - } - - public void setQuality(int quality) { - mQuality = quality; - } - - public int getQuality() { - return mQuality; - } - - public void setFiltersManager(FiltersManagerInterface filtersManager) { - mFiltersManager = filtersManager; - } - - public FiltersManagerInterface getFiltersManager() { - 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.setGeneralParameters(); - filter.setEnvironment(null); - } - - public Bitmap applyRepresentation(FilterRepresentation representation, Bitmap bitmap) { - ImageFilter filter = mFiltersManager.getFilterForRepresentation(representation); - filter.useRepresentation(representation); - filter.setEnvironment(this); - Bitmap ret = filter.apply(bitmap, mScaleFactor, mQuality); - filter.setGeneralParameters(); - filter.setEnvironment(null); - return ret; - } - - public PipelineInterface getPipeline() { - return mPipeline; - } - - public void setPipeline(PipelineInterface cachingPipeline) { - mPipeline = cachingPipeline; - } - - public synchronized void clearGeneralParameters() { - generalParameters = null; - } - - public synchronized Integer getGeneralParameter(int id) { - if (generalParameters == null || !generalParameters.containsKey(id)) { - return null; - } - return generalParameters.get(id); - } - - public synchronized void setGeneralParameter(int id, int value) { - if (generalParameters == null) { - generalParameters = new HashMap(); - } - - generalParameters.put(id, value); - } - -} diff --git a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java b/src/com/android/gallery3d/filtershow/presets/ImagePreset.java deleted file mode 100644 index d36bafd43..000000000 --- a/src/com/android/gallery3d/filtershow/presets/ImagePreset.java +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.presets; - -import android.graphics.Bitmap; -import android.graphics.Rect; -import android.support.v8.renderscript.Allocation; -import android.util.JsonReader; -import android.util.JsonWriter; -import android.util.Log; - -import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.cache.CachingPipeline; -import com.android.gallery3d.filtershow.cache.ImageLoader; -import com.android.gallery3d.filtershow.filters.BaseFiltersManager; -import com.android.gallery3d.filtershow.filters.FilterFxRepresentation; -import com.android.gallery3d.filtershow.filters.FilterImageBorderRepresentation; -import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.filters.FiltersManager; -import com.android.gallery3d.filtershow.filters.ImageFilter; -import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; -import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.state.State; -import com.android.gallery3d.filtershow.state.StateAdapter; -import com.android.gallery3d.util.UsageStatistics; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Vector; - -public class ImagePreset { - - private static final String LOGTAG = "ImagePreset"; - - private ImageLoader mImageLoader = null; - - private Vector mFilters = new Vector(); - - protected boolean mIsFxPreset = false; - - private boolean mDoApplyGeometry = true; - private boolean mDoApplyFilters = true; - - private boolean mPartialRendering = false; - private Rect mPartialRenderingBounds; - private static final boolean DEBUG = true; - - public ImagePreset() { - } - - public ImagePreset(ImagePreset source) { - try { - for (int i = 0; i < source.mFilters.size(); i++) { - FilterRepresentation representation = null; - FilterRepresentation sourceRepresentation = source.mFilters.elementAt(i); - if (sourceRepresentation instanceof GeometryMetadata) { - GeometryMetadata geoData = new GeometryMetadata(); - GeometryMetadata srcGeo = (GeometryMetadata) sourceRepresentation; - geoData.set(srcGeo); - representation = geoData; - } else { - // TODO: get rid of clone()... - representation = sourceRepresentation.clone(); - } - addFilter(representation); - } - } catch (java.lang.CloneNotSupportedException e) { - Log.v(LOGTAG, "Exception trying to clone: " + e); - } - mImageLoader = source.getImageLoader(); - } - - public FilterRepresentation getFilterRepresentation(int position) { - FilterRepresentation representation = null; - try { - representation = mFilters.elementAt(position).clone(); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - return representation; - } - - public int getPositionForRepresentation(FilterRepresentation representation) { - for (int i = 0; i < mFilters.size(); i++) { - if (mFilters.elementAt(i).getFilterClass() == representation.getFilterClass()) { - return i; - } - } - return -1; - } - - private FilterRepresentation getFilterRepresentationForType(int type) { - for (int i = 0; i < mFilters.size(); i++) { - if (mFilters.elementAt(i).getFilterType() == type) { - return mFilters.elementAt(i); - } - } - return null; - } - - public int getPositionForType(int type) { - for (int i = 0; i < mFilters.size(); i++) { - if (mFilters.elementAt(i).getFilterType() == type) { - return i; - } - } - return -1; - } - - public FilterRepresentation getFilterRepresentationCopyFrom(FilterRepresentation filterRepresentation) { - // TODO: add concept of position in the filters (to allow multiple instances) - if (filterRepresentation == null) { - return null; - } - int position = getPositionForRepresentation(filterRepresentation); - if (position == -1) { - return null; - } - FilterRepresentation representation = mFilters.elementAt(position); - if (representation != null) { - try { - representation = representation.clone(); - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } - } - return representation; - } - - public void updateFilterRepresentation(FilterRepresentation representation) { - if (representation == null) { - return; - } - if (representation instanceof GeometryMetadata) { - setGeometry((GeometryMetadata) representation); - } else { - int position = getPositionForRepresentation(representation); - if (position == -1) { - return; - } - FilterRepresentation old = mFilters.elementAt(position); - old.useParametersFrom(representation); - } - MasterImage.getImage().invalidatePreview(); - fillImageStateAdapter(MasterImage.getImage().getState()); - } - - public void setDoApplyGeometry(boolean value) { - mDoApplyGeometry = value; - } - - public void setDoApplyFilters(boolean value) { - mDoApplyFilters = value; - } - - public boolean getDoApplyFilters() { - return mDoApplyFilters; - } - - public GeometryMetadata getGeometry() { - for (FilterRepresentation representation : mFilters) { - if (representation instanceof GeometryMetadata) { - return (GeometryMetadata) representation; - } - } - GeometryMetadata geo = new GeometryMetadata(); - mFilters.add(0, geo); // Hard Requirement for now -- Geometry ought to be first. - return geo; - } - - public boolean hasModifications() { - for (int i = 0; i < mFilters.size(); i++) { - FilterRepresentation filter = mFilters.elementAt(i); - if (filter instanceof GeometryMetadata) { - if (((GeometryMetadata) filter).hasModifications()) { - return true; - } - } else if (!filter.isNil()) { - return true; - } - } - return false; - } - - public boolean isPanoramaSafe() { - for (FilterRepresentation representation : mFilters) { - if (representation instanceof GeometryMetadata) { - if (((GeometryMetadata) representation).hasModifications()) { - return false; - } - } - if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER - && !representation.isNil()) { - return false; - } - if (representation.getFilterType() == FilterRepresentation.TYPE_VIGNETTE - && !representation.isNil()) { - return false; - } - if (representation.getFilterType() == FilterRepresentation.TYPE_TINYPLANET - && !representation.isNil()) { - return false; - } - } - return true; - } - - public void setGeometry(GeometryMetadata representation) { - GeometryMetadata geoData = getGeometry(); - if (geoData != representation) { - geoData.set(representation); - } - } - - public ImageLoader getImageLoader() { - return mImageLoader; - } - - public void setImageLoader(ImageLoader mImageLoader) { - this.mImageLoader = mImageLoader; - } - - public boolean equals(ImagePreset preset) { - if (!same(preset)) { - return false; - } - if (mDoApplyFilters && preset.mDoApplyFilters) { - for (int i = 0; i < preset.mFilters.size(); i++) { - FilterRepresentation a = preset.mFilters.elementAt(i); - FilterRepresentation b = mFilters.elementAt(i); - if (!a.equals(b)) { - return false; - } - } - } - return true; - } - - public boolean same(ImagePreset preset) { - if (preset == null) { - return false; - } - - if (preset.mFilters.size() != mFilters.size()) { - return false; - } - - if (mDoApplyGeometry != preset.mDoApplyGeometry) { - return false; - } - - if (mDoApplyGeometry && !getGeometry().equals(preset.getGeometry())) { - return false; - } - - if (mDoApplyFilters != preset.mDoApplyFilters) { - if (mFilters.size() > 0 || preset.mFilters.size() > 0) { - return false; - } - } - - if (mDoApplyFilters && preset.mDoApplyFilters) { - for (int i = 0; i < preset.mFilters.size(); i++) { - FilterRepresentation a = preset.mFilters.elementAt(i); - FilterRepresentation b = mFilters.elementAt(i); - if (a instanceof GeometryMetadata) { - // Note: Geometry will always be at the same place - continue; - } - if (!a.same(b)) { - return false; - } - } - } - - return true; - } - - public int similarUpTo(ImagePreset preset) { - if (!getGeometry().equals(preset.getGeometry())) { - return -1; - } - - for (int i = 0; i < preset.mFilters.size(); i++) { - FilterRepresentation a = preset.mFilters.elementAt(i); - if (i < mFilters.size()) { - FilterRepresentation b = mFilters.elementAt(i); - if (!a.same(b)) { - return i; - } - if (!a.equals(b)) { - return i; - } - } else { - return i; - } - } - return preset.mFilters.size(); - } - - public void showFilters() { - Log.v(LOGTAG, "\\\\\\ showFilters -- " + mFilters.size() + " filters"); - int n = 0; - for (FilterRepresentation representation : mFilters) { - Log.v(LOGTAG, " filter " + n + " : " + representation.toString()); - n++; - } - Log.v(LOGTAG, "/// showFilters -- " + mFilters.size() + " filters"); - } - - public FilterRepresentation getLastRepresentation() { - if (mFilters.size() > 0) { - return mFilters.lastElement(); - } - return null; - } - - public void removeFilter(FilterRepresentation filterRepresentation) { - if (filterRepresentation.getFilterType() == FilterRepresentation.TYPE_BORDER) { - for (int i = 0; i < mFilters.size();i++) { - if (mFilters.elementAt(i).getFilterType() - == filterRepresentation.getFilterType()) { - mFilters.remove(i); - break; - } - } - } else { - for (int i = 0; i < mFilters.size(); i++) { - if (mFilters.elementAt(i).getFilterClass() - == filterRepresentation.getFilterClass()) { - mFilters.remove(i); - break; - } - } - } - } - - // If the filter is an "None" effect or border, then just don't add this - // filter. - public void addFilter(FilterRepresentation representation) { - if (representation instanceof GeometryMetadata) { - setGeometry((GeometryMetadata) representation); - return; - } - - if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { - removeFilter(representation); - if (!isNoneBorderFilter(representation)) { - mFilters.add(representation); - } - } else if (representation.getFilterType() == FilterRepresentation.TYPE_FX) { - boolean found = false; - for (int i = 0; i < mFilters.size(); i++) { - int type = mFilters.elementAt(i).getFilterType(); - if (found) { - if (type != FilterRepresentation.TYPE_VIGNETTE) { - mFilters.remove(i); - continue; - } - } - if (type == FilterRepresentation.TYPE_FX) { - mFilters.remove(i); - if (!isNoneFxFilter(representation)) { - mFilters.add(i, representation); - } - found = true; - } - } - if (!found) { - if (!isNoneFxFilter(representation)) { - mFilters.add(representation); - } - } - } else { - mFilters.add(representation); - } - } - - private boolean isNoneBorderFilter(FilterRepresentation representation) { - return representation instanceof FilterImageBorderRepresentation && - ((FilterImageBorderRepresentation) representation).getDrawableResource() == 0; - } - - private boolean isNoneFxFilter(FilterRepresentation representation) { - return representation instanceof FilterFxRepresentation && - ((FilterFxRepresentation)representation).getNameResource() == R.string.none; - } - - public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) { - for (int i = 0; i < mFilters.size(); i++) { - FilterRepresentation representation = mFilters.elementAt(i); - if (representation.getFilterClass() == filterRepresentation.getFilterClass()) { - return representation; - } - } - return null; - } - - public Bitmap apply(Bitmap original, FilterEnvironment environment) { - Bitmap bitmap = original; - bitmap = applyFilters(bitmap, -1, -1, environment); - return applyBorder(bitmap, environment); - } - - public Bitmap applyGeometry(Bitmap bitmap, FilterEnvironment environment) { - // Apply any transform -- 90 rotate, flip, straighten, crop - // Returns a new bitmap. - if (mDoApplyGeometry) { - GeometryMetadata geoData = getGeometry(); - bitmap = environment.applyRepresentation(geoData, bitmap); - } - return bitmap; - } - - public Bitmap applyBorder(Bitmap bitmap, FilterEnvironment environment) { - // get the border from the list of filters. - FilterRepresentation border = getFilterRepresentationForType( - FilterRepresentation.TYPE_BORDER); - if (border != null && mDoApplyGeometry) { - bitmap = environment.applyRepresentation(border, bitmap); - if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { - UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, - "SaveBorder", border.getSerializationName(), 1); - } - } - return bitmap; - } - - public int nbFilters() { - return mFilters.size(); - } - - public Bitmap applyFilters(Bitmap bitmap, int from, int to, FilterEnvironment environment) { - if (mDoApplyFilters) { - if (from < 0) { - from = 0; - } - if (to == -1) { - to = mFilters.size(); - } - if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { - UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, - "SaveFilters", "Total", to - from + 1); - } - for (int i = from; i < to; i++) { - FilterRepresentation representation = mFilters.elementAt(i); - if (representation instanceof GeometryMetadata) { - // skip the geometry as it's already applied. - continue; - } - if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { - // for now, let's skip the border as it will be applied in applyBorder() - // TODO: might be worth getting rid of applyBorder. - continue; - } - bitmap = environment.applyRepresentation(representation, bitmap); - if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { - UsageStatistics.onEvent(UsageStatistics.COMPONENT_EDITOR, - "SaveFilter", representation.getSerializationName(), 1); - } - if (environment.needsStop()) { - return bitmap; - } - } - } - - return bitmap; - } - - public void applyBorder(Allocation in, Allocation out, - boolean copyOut, FilterEnvironment environment) { - FilterRepresentation border = getFilterRepresentationForType( - FilterRepresentation.TYPE_BORDER); - if (border != null && mDoApplyGeometry) { - // TODO: should keep the bitmap around - Allocation bitmapIn = in; - if (copyOut) { - bitmapIn = Allocation.createTyped( - CachingPipeline.getRenderScriptContext(), in.getType()); - bitmapIn.copyFrom(out); - } - environment.applyRepresentation(border, bitmapIn, out); - } - } - - 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 = mFilters.elementAt(i); - if (representation instanceof GeometryMetadata) { - // skip the geometry as it's already applied. - continue; - } - if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { - // for now, let's skip the border as it will be applied in applyBorder() - continue; - } - if (i > from) { - in.copyFrom(out); - } - environment.applyRepresentation(representation, in, out); - } - } - } - - public boolean canDoPartialRendering() { - if (ImageLoader.getZoomOrientation() != ImageLoader.ORI_NORMAL) { - return false; - } - for (int i = 0; i < mFilters.size(); i++) { - FilterRepresentation representation = mFilters.elementAt(i); - if (representation instanceof GeometryMetadata - && ((GeometryMetadata) representation).hasModifications()) { - return false; - } - if (!representation.supportsPartialRendering()) { - return false; - } - } - return true; - } - - public void fillImageStateAdapter(StateAdapter imageStateAdapter) { - if (imageStateAdapter == null) { - return; - } - Vector states = new Vector(); - for (FilterRepresentation filter : mFilters) { - if (filter instanceof GeometryMetadata) { - // TODO: supports Geometry representations in the state panel. - continue; - } - State state = new State(filter.getName()); - state.setFilterRepresentation(filter); - states.add(state); - } - imageStateAdapter.fill(states); - } - - public void setPartialRendering(boolean partialRendering, Rect bounds) { - mPartialRendering = partialRendering; - mPartialRenderingBounds = bounds; - } - - public boolean isPartialRendering() { - return mPartialRendering; - } - - public Rect getPartialRenderingBounds() { - return mPartialRenderingBounds; - } - - public Vector getUsedFilters(BaseFiltersManager filtersManager) { - Vector usedFilters = new Vector(); - for (int i = 0; i < mFilters.size(); i++) { - FilterRepresentation representation = mFilters.elementAt(i); - ImageFilter filter = filtersManager.getFilterForRepresentation(representation); - usedFilters.add(filter); - } - return usedFilters; - } - - public String getJsonString(String name) { - StringWriter swriter = new StringWriter(); - try { - JsonWriter writer = new JsonWriter(swriter); - writeJson(writer, name); - writer.close(); - } catch (IOException e) { - return null; - } - return swriter.toString(); - } - - public void writeJson(JsonWriter writer, String name) { - int numFilters = mFilters.size(); - try { - writer.beginObject(); - GeometryMetadata geoData = getGeometry(); - writer.name(geoData.getSerializationName()); - writer.beginObject(); - { - String[][] rep = geoData.serializeRepresentation(); - for (int i = 0; i < rep.length; i++) { - writer.name(rep[i][0]); - writer.value(rep[i][1]); - } - } - writer.endObject(); - - for (int i = 0; i < numFilters; i++) { - FilterRepresentation filter = mFilters.get(i); - if (filter instanceof GeometryMetadata) { - continue; - } - String sname = filter.getSerializationName(); - if (DEBUG) { - Log.v(LOGTAG, "Serialization: " + sname); - if (sname == null) { - Log.v(LOGTAG, "Serialization: " + filter); - } - } - writer.name(sname); - filter.serializeRepresentation(writer); - } - writer.endObject(); - - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * populates preset from JSON string - * @param filterString a JSON string - * @return true on success if false ImagePreset is undefined - */ - public boolean readJsonFromString(String filterString) { - if (DEBUG) { - Log.v(LOGTAG,"reading preset: \""+filterString+"\""); - } - StringReader sreader = new StringReader(filterString); - try { - JsonReader reader = new JsonReader(sreader); - boolean ok = readJson(reader); - if (!ok) { - reader.close(); - return false; - } - reader.close(); - } catch (Exception e) { - Log.e(LOGTAG,"parsing the filter parameters:",e); - return false; - } - return true; - } - - /** - * populates preset from JSON stream - * @param sreader a JSON string - * @return true on success if false ImagePreset is undefined - */ - public boolean readJson(JsonReader sreader) throws IOException { - sreader.beginObject(); - - while (sreader.hasNext()) { - String name = sreader.nextName(); - FilterRepresentation filter = creatFilterFromName(name); - if (filter == null) { - Log.w(LOGTAG,"UNKNOWN FILTER! "+name); - return false; - } - filter.deSerializeRepresentation(sreader); - addFilter(filter); - } - sreader.endObject(); - return true; - } - - FilterRepresentation creatFilterFromName(String name) { - if (GeometryMetadata.SERIALIZATION_NAME.equalsIgnoreCase(name)) { - return new GeometryMetadata(); - } - FiltersManager filtersManager = FiltersManager.getManager(); - return filtersManager.createFilterFromName(name); - } - - public void updateWith(ImagePreset preset) { - if (preset.mFilters.size() != mFilters.size()) { - Log.e(LOGTAG, "Updating a preset with an incompatible one"); - return; - } - for (int i = 0; i < mFilters.size(); i++) { - FilterRepresentation destRepresentation = mFilters.elementAt(i); - FilterRepresentation sourceRepresentation = preset.mFilters.elementAt(i); - destRepresentation.useParametersFrom(sourceRepresentation); - } - } -} diff --git a/src/com/android/gallery3d/filtershow/presets/PipelineInterface.java b/src/com/android/gallery3d/filtershow/presets/PipelineInterface.java deleted file mode 100644 index 05f0a1aa8..000000000 --- a/src/com/android/gallery3d/filtershow/presets/PipelineInterface.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.filtershow.presets; - -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.support.v8.renderscript.Allocation; -import android.support.v8.renderscript.RenderScript; - -public interface PipelineInterface { - public String getName(); - public Resources getResources(); - public Allocation getInPixelsAllocation(); - public Allocation getOutPixelsAllocation(); - public boolean prepareRenderscriptAllocations(Bitmap bitmap); - public RenderScript getRSContext(); -} diff --git a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java index ee2ce9672..1d5500ef4 100644 --- a/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java +++ b/src/com/android/gallery3d/filtershow/tools/SaveCopyTask.java @@ -32,10 +32,10 @@ import android.util.Log; import com.android.gallery3d.common.Utils; import com.android.gallery3d.exif.ExifInterface; -import com.android.gallery3d.filtershow.cache.CachingPipeline; +import com.android.gallery3d.filtershow.pipeline.CachingPipeline; import com.android.gallery3d.filtershow.cache.ImageLoader; import com.android.gallery3d.filtershow.filters.FiltersManager; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.util.UsageStatistics; import com.android.gallery3d.util.XmpUtilHelper; diff --git a/src/com/android/gallery3d/filtershow/tools/XmpPresets.java b/src/com/android/gallery3d/filtershow/tools/XmpPresets.java index be75f0253..3995eeb85 100644 --- a/src/com/android/gallery3d/filtershow/tools/XmpPresets.java +++ b/src/com/android/gallery3d/filtershow/tools/XmpPresets.java @@ -26,7 +26,7 @@ import com.adobe.xmp.XMPMetaFactory; import com.android.gallery3d.R; import com.android.gallery3d.common.Utils; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.util.XmpUtilHelper; import java.io.File; diff --git a/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java b/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java index bc41e0e9c..af965a359 100644 --- a/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java +++ b/src/com/android/gallery3d/filtershow/ui/FilterIconButton.java @@ -21,7 +21,6 @@ import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; @@ -32,15 +31,15 @@ import android.widget.LinearLayout; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.FilterShowActivity; -import com.android.gallery3d.filtershow.cache.RenderingRequest; -import com.android.gallery3d.filtershow.cache.RenderingRequestCaller; +import com.android.gallery3d.filtershow.pipeline.RenderingRequest; +import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; import com.android.gallery3d.filtershow.category.Action; import com.android.gallery3d.filtershow.category.CategoryAdapter; import com.android.gallery3d.filtershow.filters.FilterRepresentation; import com.android.gallery3d.filtershow.imageshow.GeometryListener; import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; import com.android.gallery3d.filtershow.imageshow.MasterImage; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import com.android.gallery3d.filtershow.tools.IconFactory; // TODO: merge back IconButton and FilterIconButton? diff --git a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java index 0bab3954f..87ab82f8b 100644 --- a/src/com/android/gallery3d/filtershow/ui/ImageCurves.java +++ b/src/com/android/gallery3d/filtershow/ui/ImageCurves.java @@ -26,8 +26,6 @@ import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.os.AsyncTask; import android.util.AttributeSet; -import android.util.Log; -import android.view.LayoutInflater; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; @@ -42,7 +40,7 @@ import com.android.gallery3d.filtershow.filters.FilterCurvesRepresentation; import com.android.gallery3d.filtershow.filters.FiltersManager; import com.android.gallery3d.filtershow.filters.ImageFilterCurves; import com.android.gallery3d.filtershow.imageshow.ImageShow; -import com.android.gallery3d.filtershow.presets.ImagePreset; +import com.android.gallery3d.filtershow.pipeline.ImagePreset; import java.util.HashMap; -- cgit v1.2.3