ImageFilterRS.java revision 0c90af2257105a289c19a355e33d4035bd1fc61f
1a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard/* 2a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Copyright (C) 2012 The Android Open Source Project 3a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * 4a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Licensed under the Apache License, Version 2.0 (the "License"); 5a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * you may not use this file except in compliance with the License. 6a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * You may obtain a copy of the License at 7a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * 8a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * http://www.apache.org/licenses/LICENSE-2.0 9a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * 10a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Unless required by applicable law or agreed to in writing, software 11a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * distributed under the License is distributed on an "AS IS" BASIS, 12a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * See the License for the specific language governing permissions and 14a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * limitations under the License. 15a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard */ 16a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard 175448bf8095483574649afcc2add7f153670c7450nicolasroardpackage com.android.gallery3d.filtershow.filters; 185448bf8095483574649afcc2add7f153670c7450nicolasroard 195448bf8095483574649afcc2add7f153670c7450nicolasroardimport android.app.Activity; 205448bf8095483574649afcc2add7f153670c7450nicolasroardimport android.graphics.Bitmap; 2196df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroardimport android.graphics.BitmapFactory; 22a64051696e46fb5d5e1c76e53ac95a4feba18585Tim Murrayimport android.support.v8.renderscript.*; 235448bf8095483574649afcc2add7f153670c7450nicolasroardimport android.util.Log; 24575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunkimport android.content.res.Resources; 25a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murrayimport com.android.gallery3d.R; 26fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroardimport com.android.gallery3d.filtershow.cache.CachingPipeline; 275448bf8095483574649afcc2add7f153670c7450nicolasroard 284e6c07b71b269ee3fe7f6fa455bc540238df9dedJohn Hofordpublic abstract class ImageFilterRS extends ImageFilter { 29575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk private static final String LOGTAG = "ImageFilterRS"; 30180277924bebf6b600ee5ce5adf9ff807a038570nicolasroard private boolean DEBUG = false; 315448bf8095483574649afcc2add7f153670c7450nicolasroard 32ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk private volatile boolean mResourcesLoaded = false; 3357eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard 34ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk protected abstract void createFilter(android.content.res.Resources res, 357706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard float scaleFactor, int quality); 365448bf8095483574649afcc2add7f153670c7450nicolasroard 37ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk protected abstract void runFilter(); 385448bf8095483574649afcc2add7f153670c7450nicolasroard 39ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk protected void update(Bitmap bitmap) { 40fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard getOutPixelsAllocation().copyTo(bitmap); 41fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard } 42fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard 43560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard protected RenderScript getRenderScriptContext() { 44560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard return CachingPipeline.getRenderScriptContext(); 45560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard } 46560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard 47fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard protected Allocation getInPixelsAllocation() { 48fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard CachingPipeline pipeline = getEnvironment().getCachingPipeline(); 49fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard return pipeline.getInPixelsAllocation(); 50fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard } 51fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard 52fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard protected Allocation getOutPixelsAllocation() { 53fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard CachingPipeline pipeline = getEnvironment().getCachingPipeline(); 54fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard return pipeline.getOutPixelsAllocation(); 555448bf8095483574649afcc2add7f153670c7450nicolasroard } 565448bf8095483574649afcc2add7f153670c7450nicolasroard 5781eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard @Override 5899baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) { 59575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0) { 6081eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard return bitmap; 615448bf8095483574649afcc2add7f153670c7450nicolasroard } 625448bf8095483574649afcc2add7f153670c7450nicolasroard try { 63560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard CachingPipeline pipeline = getEnvironment().getCachingPipeline(); 64560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard if (DEBUG) { 65560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Log.v(LOGTAG, "apply filter " + getName() + " in pipeline " + pipeline.getName()); 66560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard } 67560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Resources rsc = pipeline.getResources(); 680c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard if (pipeline.prepareRenderscriptAllocations(bitmap) 690c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard || !isResourcesLoaded()) { 700c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard freeResources(); 710c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard createFilter(rsc, scaleFactor, quality); 720c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard setResourcesLoaded(true); 730c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard } 740c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard bindScriptValues(); 75560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard runFilter(); 76560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard update(bitmap); 77560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard if (DEBUG) { 78560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Log.v(LOGTAG, "DONE apply filter " + getName() + " in pipeline " + pipeline.getName()); 79575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk } 805448bf8095483574649afcc2add7f153670c7450nicolasroard } catch (android.renderscript.RSIllegalArgumentException e) { 815448bf8095483574649afcc2add7f153670c7450nicolasroard Log.e(LOGTAG, "Illegal argument? " + e); 825448bf8095483574649afcc2add7f153670c7450nicolasroard } catch (android.renderscript.RSRuntimeException e) { 835448bf8095483574649afcc2add7f153670c7450nicolasroard Log.e(LOGTAG, "RS runtime exception ? " + e); 84b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk } catch (java.lang.OutOfMemoryError e) { 85b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk // Many of the renderscript filters allocated large (>16Mb resources) in order to apply. 86b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk System.gc(); 87b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk displayLowMemoryToast(); 88b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk Log.e(LOGTAG, "not enough memory for filter " + getName(), e); 895448bf8095483574649afcc2add7f153670c7450nicolasroard } 9081eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard return bitmap; 915448bf8095483574649afcc2add7f153670c7450nicolasroard } 925448bf8095483574649afcc2add7f153670c7450nicolasroard 93560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard private static Allocation convertBitmap(Bitmap bitmap) { 94560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard return Allocation.createFromBitmap(CachingPipeline.getRenderScriptContext(), bitmap, 9596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT); 9696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard } 9796df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard 98560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard private static Allocation convertRGBAtoA(Bitmap bitmap) { 99560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard RenderScript RS = CachingPipeline.getRenderScriptContext(); 100560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Type.Builder tb_a8 = new Type.Builder(RS, Element.A_8(RS)); 101560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard ScriptC_grey greyConvert = new ScriptC_grey(RS, 102560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard RS.getApplicationContext().getResources(), R.raw.grey); 103a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray 10496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard Allocation bitmapTemp = convertBitmap(bitmap); 105560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard if (bitmapTemp.getType().getElement().isCompatible(Element.A_8(RS))) { 106a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray return bitmapTemp; 107a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray } 108a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray 109a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray tb_a8.setX(bitmapTemp.getType().getX()); 110a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray tb_a8.setY(bitmapTemp.getType().getY()); 111560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Allocation bitmapAlloc = Allocation.createTyped(RS, tb_a8.create()); 112a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray greyConvert.forEach_RGBAtoA(bitmapTemp, bitmapAlloc); 113a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray 114a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray return bitmapAlloc; 1157706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard } 116a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray 1170055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba public Allocation loadScaledResourceAlpha(int resource, int inSampleSize) { 118560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Resources res = CachingPipeline.getResources(); 11996df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard final BitmapFactory.Options options = new BitmapFactory.Options(); 12096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard options.inPreferredConfig = Bitmap.Config.ALPHA_8; 1210055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba options.inSampleSize = inSampleSize; 12296df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard Bitmap bitmap = BitmapFactory.decodeResource( 123575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk res, 12496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard resource, options); 12596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard Allocation ret = convertRGBAtoA(bitmap); 12696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard bitmap.recycle(); 12796df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard return ret; 12896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard } 12996df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard 1300055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba public Allocation loadResourceAlpha(int resource) { 1310055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba return loadScaledResourceAlpha(resource, 1); 1320055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba } 1330055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba 13496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard public Allocation loadResource(int resource) { 135560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard Resources res = CachingPipeline.getResources(); 13696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard final BitmapFactory.Options options = new BitmapFactory.Options(); 13796df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard options.inPreferredConfig = Bitmap.Config.ARGB_8888; 13896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard Bitmap bitmap = BitmapFactory.decodeResource( 139575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk res, 14096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard resource, options); 14196df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard Allocation ret = convertBitmap(bitmap); 14296df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard bitmap.recycle(); 14396df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard return ret; 14496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard } 14596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard 146575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk private boolean isResourcesLoaded() { 1477706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard return mResourcesLoaded; 148a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray } 149a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray 150575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk private void setResourcesLoaded(boolean resourcesLoaded) { 1517706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard mResourcesLoaded = resourcesLoaded; 1527706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard } 1537706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard 154f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk /** 155f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk * Bitmaps and RS Allocations should be cleared here 156f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk */ 1577706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard abstract protected void resetAllocations(); 1587706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard 159f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk /** 160f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk * RS Script objects (and all other RS objects) should be cleared here 161f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk */ 162f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk abstract protected void resetScripts(); 163f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk 1640c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard /** 1650c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard * Scripts values should be bound here 1660c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard */ 1670c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard abstract protected void bindScriptValues(); 1680c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard 1697706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard public void freeResources() { 1707706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard if (!isResourcesLoaded()) { 1717706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard return; 1727706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard } 173560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard resetAllocations(); 174560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard setResourcesLoaded(false); 1757706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard } 1765448bf8095483574649afcc2add7f153670c7450nicolasroard} 177