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.graphics.Bitmap;
2096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroardimport android.graphics.BitmapFactory;
21a64051696e46fb5d5e1c76e53ac95a4feba18585Tim Murrayimport android.support.v8.renderscript.*;
225448bf8095483574649afcc2add7f153670c7450nicolasroardimport android.util.Log;
23575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunkimport android.content.res.Resources;
24a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murrayimport com.android.gallery3d.R;
25ce9ceff5776a9b0479c30cbeb2a9388b44df1865nicolasroardimport com.android.gallery3d.filtershow.pipeline.PipelineInterface;
265448bf8095483574649afcc2add7f153670c7450nicolasroard
274e6c07b71b269ee3fe7f6fa455bc540238df9dedJohn Hofordpublic abstract class ImageFilterRS extends ImageFilter {
28575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static final String LOGTAG = "ImageFilterRS";
29180277924bebf6b600ee5ce5adf9ff807a038570nicolasroard    private boolean DEBUG = false;
302538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard    private int mLastInputWidth = 0;
312538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard    private int mLastInputHeight = 0;
328b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard    private long mLastTimeCalled;
335448bf8095483574649afcc2add7f153670c7450nicolasroard
3493ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    public static boolean PERF_LOGGING = false;
3593ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard
36e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray    private static ScriptC_grey mGreyConvert = null;
37e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray    private static RenderScript mRScache = null;
38e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray
39ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    private volatile boolean mResourcesLoaded = false;
4057eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard
41ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected abstract void createFilter(android.content.res.Resources res,
427706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard            float scaleFactor, int quality);
435448bf8095483574649afcc2add7f153670c7450nicolasroard
4493ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    protected void createFilter(android.content.res.Resources res,
4593ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    float scaleFactor, int quality, Allocation in) {}
4693ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    protected void bindScriptValues(Allocation in) {}
4793ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard
48ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected abstract void runFilter();
495448bf8095483574649afcc2add7f153670c7450nicolasroard
50ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected void update(Bitmap bitmap) {
51fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard        getOutPixelsAllocation().copyTo(bitmap);
52fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard    }
53fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard
54560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard    protected RenderScript getRenderScriptContext() {
5536e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        PipelineInterface pipeline = getEnvironment().getPipeline();
5636e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        return pipeline.getRSContext();
57560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard    }
58560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard
59fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard    protected Allocation getInPixelsAllocation() {
6036e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        PipelineInterface pipeline = getEnvironment().getPipeline();
61fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard        return pipeline.getInPixelsAllocation();
62fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard    }
63fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard
64fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard    protected Allocation getOutPixelsAllocation() {
6536e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        PipelineInterface pipeline = getEnvironment().getPipeline();
66fc8a6a38c699c0d75fa29664d9aaa369d361c335nicolasroard        return pipeline.getOutPixelsAllocation();
675448bf8095483574649afcc2add7f153670c7450nicolasroard    }
685448bf8095483574649afcc2add7f153670c7450nicolasroard
6981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    @Override
7093ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    public void apply(Allocation in, Allocation out) {
7193ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        long startOverAll = System.nanoTime();
728b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard        if (PERF_LOGGING) {
738b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard            long delay = (startOverAll - mLastTimeCalled) / 1000;
748b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard            String msg = String.format("%s; image size %dx%d; ", getName(),
758b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard                    in.getType().getX(), in.getType().getY());
768b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard            msg += String.format("called after %.2f ms (%.2f FPS); ",
778b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard                    delay / 1000.f, 1000000.f / delay);
788b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard            Log.i(LOGTAG, msg);
798b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard        }
808b118bf1437b18eb3f6f9b5698daf43c378eacbfnicolasroard        mLastTimeCalled = startOverAll;
8193ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        long startFilter = 0;
8293ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        long endFilter = 0;
834433a05abfc33e99223d89fcc28b924cdd754104Ruben Brunk        if (!mResourcesLoaded) {
8436e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard            PipelineInterface pipeline = getEnvironment().getPipeline();
8593ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            createFilter(pipeline.getResources(), getEnvironment().getScaleFactor(),
8693ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard                    getEnvironment().getQuality(), in);
8793ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            mResourcesLoaded = true;
8893ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        }
8993ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        startFilter = System.nanoTime();
9093ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        bindScriptValues(in);
9193ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        run(in, out);
9293ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        if (PERF_LOGGING) {
9393ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            getRenderScriptContext().finish();
9493ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            endFilter = System.nanoTime();
9593ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            long endOverAll = System.nanoTime();
9693ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            String msg = String.format("%s; image size %dx%d; ", getName(),
9793ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard                    in.getType().getX(), in.getType().getY());
9893ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            long timeOverAll = (endOverAll - startOverAll) / 1000;
9993ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            long timeFilter = (endFilter - startFilter) / 1000;
10093ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            msg += String.format("over all %.2f ms (%.2f FPS); ",
10193ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard                    timeOverAll / 1000.f, 1000000.f / timeOverAll);
10293ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            msg += String.format("run filter %.2f ms (%.2f FPS)",
10393ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard                    timeFilter / 1000.f, 1000000.f / timeFilter);
10493ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard            Log.i(LOGTAG, msg);
10593ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        }
10693ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    }
10793ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard
10893ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    protected void run(Allocation in, Allocation out) {}
10993ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard
11093ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    @Override
11199baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford    public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
112575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
11381eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard            return bitmap;
1145448bf8095483574649afcc2add7f153670c7450nicolasroard        }
1155448bf8095483574649afcc2add7f153670c7450nicolasroard        try {
11636e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard            PipelineInterface pipeline = getEnvironment().getPipeline();
117560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard            if (DEBUG) {
118560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard                Log.v(LOGTAG, "apply filter " + getName() + " in pipeline " + pipeline.getName());
119560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard            }
120560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard            Resources rsc = pipeline.getResources();
1212538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard            boolean sizeChanged = false;
1222538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard            if (getInPixelsAllocation() != null
1232538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard                    && ((getInPixelsAllocation().getType().getX() != mLastInputWidth)
1242538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard                    || (getInPixelsAllocation().getType().getY() != mLastInputHeight))) {
1252538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard                sizeChanged = true;
1262538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard            }
1270c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard            if (pipeline.prepareRenderscriptAllocations(bitmap)
1284433a05abfc33e99223d89fcc28b924cdd754104Ruben Brunk                    || !isResourcesLoaded() || sizeChanged) {
1290c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard                freeResources();
1300c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard                createFilter(rsc, scaleFactor, quality);
1310c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard                setResourcesLoaded(true);
1322538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard                mLastInputWidth = getInPixelsAllocation().getType().getX();
1332538c992dc70b3eda7487ef68dba0390b2f337d7nicolasroard                mLastInputHeight = getInPixelsAllocation().getType().getY();
1340c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard            }
1350c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard            bindScriptValues();
136560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard            runFilter();
137560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard            update(bitmap);
138560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard            if (DEBUG) {
139560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard                Log.v(LOGTAG, "DONE apply filter " + getName() + " in pipeline " + pipeline.getName());
140575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            }
1415448bf8095483574649afcc2add7f153670c7450nicolasroard        } catch (android.renderscript.RSIllegalArgumentException e) {
1425448bf8095483574649afcc2add7f153670c7450nicolasroard            Log.e(LOGTAG, "Illegal argument? " + e);
1435448bf8095483574649afcc2add7f153670c7450nicolasroard        } catch (android.renderscript.RSRuntimeException e) {
1445448bf8095483574649afcc2add7f153670c7450nicolasroard            Log.e(LOGTAG, "RS runtime exception ? " + e);
145b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk        } catch (java.lang.OutOfMemoryError e) {
146b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            // Many of the renderscript filters allocated large (>16Mb resources) in order to apply.
147b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            System.gc();
148b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            displayLowMemoryToast();
149b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            Log.e(LOGTAG, "not enough memory for filter " + getName(), e);
1505448bf8095483574649afcc2add7f153670c7450nicolasroard        }
15181eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        return bitmap;
1525448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1535448bf8095483574649afcc2add7f153670c7450nicolasroard
15436e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard    protected static Allocation convertBitmap(RenderScript RS, Bitmap bitmap) {
15536e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        return Allocation.createFromBitmap(RS, bitmap,
1567a584e068d274ca95286fcf2804c068d38fe8753Tim Murray                Allocation.MipmapControl.MIPMAP_NONE,
1577a584e068d274ca95286fcf2804c068d38fe8753Tim Murray                Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_TEXTURE);
15896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    }
15996df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard
16036e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard    private static Allocation convertRGBAtoA(RenderScript RS, Bitmap bitmap) {
161e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray        if (RS != mRScache || mGreyConvert == null) {
162e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray            mGreyConvert = new ScriptC_grey(RS, RS.getApplicationContext().getResources(),
163e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray                                            R.raw.grey);
164e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray            mRScache = RS;
165e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray        }
166e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray
167560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard        Type.Builder tb_a8 = new Type.Builder(RS, Element.A_8(RS));
168a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
16936e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Allocation bitmapTemp = convertBitmap(RS, bitmap);
170560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard        if (bitmapTemp.getType().getElement().isCompatible(Element.A_8(RS))) {
171a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray            return bitmapTemp;
172a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        }
173a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
174a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        tb_a8.setX(bitmapTemp.getType().getX());
175a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        tb_a8.setY(bitmapTemp.getType().getY());
1767a584e068d274ca95286fcf2804c068d38fe8753Tim Murray        Allocation bitmapAlloc = Allocation.createTyped(RS, tb_a8.create(),
1777a584e068d274ca95286fcf2804c068d38fe8753Tim Murray                                                        Allocation.MipmapControl.MIPMAP_NONE,
1787a584e068d274ca95286fcf2804c068d38fe8753Tim Murray                                                        Allocation.USAGE_SCRIPT | Allocation.USAGE_GRAPHICS_TEXTURE);
179e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray        mGreyConvert.forEach_RGBAtoA(bitmapTemp, bitmapAlloc);
180e193e864a849f4f816c55cff83a9dc7b39e0018fTim Murray        bitmapTemp.destroy();
181a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        return bitmapAlloc;
1827706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    }
183a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
1840055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba    public Allocation loadScaledResourceAlpha(int resource, int inSampleSize) {
18536e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Resources res = getEnvironment().getPipeline().getResources();
18696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        final BitmapFactory.Options options = new BitmapFactory.Options();
1870055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba        options.inSampleSize      = inSampleSize;
18896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Bitmap bitmap = BitmapFactory.decodeResource(
189575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                res,
19096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard                resource, options);
19136e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Allocation ret = convertRGBAtoA(getRenderScriptContext(), bitmap);
19296df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        bitmap.recycle();
19396df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        return ret;
19496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    }
19596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard
19693ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    public Allocation loadScaledResourceAlpha(int resource, int w, int h, int inSampleSize) {
19736e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Resources res = getEnvironment().getPipeline().getResources();
19893ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        final BitmapFactory.Options options = new BitmapFactory.Options();
19993ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        options.inSampleSize      = inSampleSize;
20093ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        Bitmap bitmap = BitmapFactory.decodeResource(
20193ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard                res,
20293ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard                resource, options);
20393ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        Bitmap resizeBitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
20436e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Allocation ret = convertRGBAtoA(getRenderScriptContext(), resizeBitmap);
20593ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        resizeBitmap.recycle();
20693ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        bitmap.recycle();
20793ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard        return ret;
20893ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard    }
20993ef658bf44d7ecd79894a9a225a400c2741058fnicolasroard
2100055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba    public Allocation loadResourceAlpha(int resource) {
2110055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba        return loadScaledResourceAlpha(resource, 1);
2120055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba    }
2130055102404c767af2cd5fabf70acbc8317e33fe3Victor Doba
21496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    public Allocation loadResource(int resource) {
21536e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Resources res = getEnvironment().getPipeline().getResources();
21696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        final BitmapFactory.Options options = new BitmapFactory.Options();
21796df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
21896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Bitmap bitmap = BitmapFactory.decodeResource(
219575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                res,
22096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard                resource, options);
22136e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard        Allocation ret = convertBitmap(getRenderScriptContext(), bitmap);
22296df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        bitmap.recycle();
22396df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        return ret;
22496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    }
22596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard
226575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private boolean isResourcesLoaded() {
2277706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        return mResourcesLoaded;
228a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray    }
229a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
230575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private void setResourcesLoaded(boolean resourcesLoaded) {
2317706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        mResourcesLoaded = resourcesLoaded;
2327706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    }
2337706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard
234f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk    /**
235f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     *  Bitmaps and RS Allocations should be cleared here
236f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     */
2377706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    abstract protected void resetAllocations();
2387706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard
239f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk    /**
240f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     * RS Script objects (and all other RS objects) should be cleared here
241f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     */
24236e567afff815bc821c2859ebdeec86b1fca1ef6nicolasroard    public abstract void resetScripts();
243f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk
2440c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard    /**
2450c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard     * Scripts values should be bound here
2460c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard     */
2470c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard    abstract protected void bindScriptValues();
2480c90af2257105a289c19a355e33d4035bd1fc61fnicolasroard
2497706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    public void freeResources() {
2507706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        if (!isResourcesLoaded()) {
2517706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard            return;
2527706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        }
253560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard        resetAllocations();
254fc47c52f552ad8ed6adfc177e9ba90b1f4e93ca4Ruben Brunk        mLastInputWidth = 0;
255fc47c52f552ad8ed6adfc177e9ba90b1f4e93ca4Ruben Brunk        mLastInputHeight = 0;
256560f959b659bb510a6ac9a92831534c5dfcf16benicolasroard        setResourcesLoaded(false);
2577706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    }
2585448bf8095483574649afcc2add7f153670c7450nicolasroard}
259