ImageFilterRS.java revision f79f954f4eb23bce55061c683a07fc7b3a965451
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;
265448bf8095483574649afcc2add7f153670c7450nicolasroard
274e6c07b71b269ee3fe7f6fa455bc540238df9dedJohn Hofordpublic abstract class ImageFilterRS extends ImageFilter {
28575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static final String LOGTAG = "ImageFilterRS";
295448bf8095483574649afcc2add7f153670c7450nicolasroard
30575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    protected static volatile Allocation mInPixelsAllocation;
31575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    protected static volatile Allocation mOutPixelsAllocation;
325448bf8095483574649afcc2add7f153670c7450nicolasroard
33575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static volatile RenderScript sRS = null;
34575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static volatile int sWidth = 0;
35575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static volatile int sHeight = 0;
367706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard
37575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static volatile Resources sResources = null;
38ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    private volatile boolean mResourcesLoaded = false;
3957eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard
40575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
41b01a32825018cfb79f2c965c1c3e3e25b5131229nicolasroard
42575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    // This must be used inside block synchronized on ImageFilterRS class object
43ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected void prepare(Bitmap bitmap, float scaleFactor, int quality) {
44575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        if (mOutPixelsAllocation == null || mInPixelsAllocation == null ||
45575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                bitmap.getWidth() != sWidth || bitmap.getHeight() != sHeight) {
46575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            destroyPixelAllocations();
47575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            Bitmap bitmapBuffer = bitmap;
48575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            if (bitmap.getConfig() == null || bitmap.getConfig() != BITMAP_CONFIG) {
49575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                bitmapBuffer = bitmap.copy(BITMAP_CONFIG, true);
5057eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            }
51575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            mOutPixelsAllocation = Allocation.createFromBitmap(sRS, bitmapBuffer,
523df4f831396ffbc11e4bbee0b6150794e8e44e0bnicolasroard                    Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
53575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            mInPixelsAllocation = Allocation.createTyped(sRS,
5457eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard                    mOutPixelsAllocation.getType());
5563a7dac01d394523799939596b960cb03321798dJohn Hoford        }
5657eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard        mInPixelsAllocation.copyFrom(bitmap);
57575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        if (bitmap.getWidth() != sWidth
58575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            || bitmap.getHeight() != sHeight || !isResourcesLoaded()) {
597706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard            freeResources();
60575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            createFilter(sResources, scaleFactor, quality);
61575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            sWidth = bitmap.getWidth();
62575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            sHeight = bitmap.getHeight();
637706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard            setResourcesLoaded(true);
6463a7dac01d394523799939596b960cb03321798dJohn Hoford        }
655448bf8095483574649afcc2add7f153670c7450nicolasroard    }
665448bf8095483574649afcc2add7f153670c7450nicolasroard
67575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    // This must be used inside block synchronized on ImageFilterRS class object
68ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected abstract void createFilter(android.content.res.Resources res,
697706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard            float scaleFactor, int quality);
705448bf8095483574649afcc2add7f153670c7450nicolasroard
71575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    // This must be used inside block synchronized on ImageFilterRS class object
72ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected abstract void runFilter();
735448bf8095483574649afcc2add7f153670c7450nicolasroard
74575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    // This must be used inside block synchronized on ImageFilterRS class object
75ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk    protected void update(Bitmap bitmap) {
765448bf8095483574649afcc2add7f153670c7450nicolasroard        mOutPixelsAllocation.copyTo(bitmap);
775448bf8095483574649afcc2add7f153670c7450nicolasroard    }
785448bf8095483574649afcc2add7f153670c7450nicolasroard
7981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    @Override
8099baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford    public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
81575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0) {
8281eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard            return bitmap;
835448bf8095483574649afcc2add7f153670c7450nicolasroard        }
845448bf8095483574649afcc2add7f153670c7450nicolasroard        try {
85575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            synchronized(ImageFilterRS.class) {
86575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                if (sRS == null)  {
87ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk                    Log.w(LOGTAG, "Cannot apply before calling createRenderScriptContext");
88575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                    return bitmap;
89575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                }
90575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                prepare(bitmap, scaleFactor, quality);
91575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                runFilter();
92575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                update(bitmap);
93575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            }
945448bf8095483574649afcc2add7f153670c7450nicolasroard        } catch (android.renderscript.RSIllegalArgumentException e) {
955448bf8095483574649afcc2add7f153670c7450nicolasroard            Log.e(LOGTAG, "Illegal argument? " + e);
965448bf8095483574649afcc2add7f153670c7450nicolasroard        } catch (android.renderscript.RSRuntimeException e) {
975448bf8095483574649afcc2add7f153670c7450nicolasroard            Log.e(LOGTAG, "RS runtime exception ? " + e);
98b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk        } catch (java.lang.OutOfMemoryError e) {
99b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            // Many of the renderscript filters allocated large (>16Mb resources) in order to apply.
100b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            System.gc();
101b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            displayLowMemoryToast();
102b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            Log.e(LOGTAG, "not enough memory for filter " + getName(), e);
1035448bf8095483574649afcc2add7f153670c7450nicolasroard        }
10481eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        return bitmap;
1055448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1065448bf8095483574649afcc2add7f153670c7450nicolasroard
107575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    public static synchronized RenderScript getRenderScriptContext() {
108575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        return sRS;
1095448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1105448bf8095483574649afcc2add7f153670c7450nicolasroard
111d7c61b63a1ea0d86cd10861834fd2783c54a4632Ruben Brunk    public static synchronized void createRenderscriptContext(Activity context) {
112575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        if( sRS != null) {
113575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            Log.w(LOGTAG, "A prior RS context exists when calling setRenderScriptContext");
114575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            destroyRenderScriptContext();
1157921e124d57759d6f0887a42ddc360d923e60cddTim Murray        }
116575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sRS = RenderScript.create(context);
117575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sResources = context.getResources();
118575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        destroyPixelAllocations();
119575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    }
120575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk
121575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static synchronized void destroyPixelAllocations() {
122588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        if (mInPixelsAllocation != null) {
123588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mInPixelsAllocation.destroy();
124588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mInPixelsAllocation = null;
125588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        }
126588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        if (mOutPixelsAllocation != null) {
127588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mOutPixelsAllocation.destroy();
128588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mOutPixelsAllocation = null;
129588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        }
130575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sWidth = 0;
131575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sHeight = 0;
132575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    }
133575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk
134575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    public static synchronized void destroyRenderScriptContext() {
135575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        destroyPixelAllocations();
136575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sRS.destroy();
137575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sRS = null;
138575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        sResources = null;
1395448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1405448bf8095483574649afcc2add7f153670c7450nicolasroard
141575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static synchronized Allocation convertBitmap(Bitmap bitmap) {
142575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        return Allocation.createFromBitmap(sRS, bitmap,
14396df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard                Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
14496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    }
14596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard
146575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private static synchronized Allocation convertRGBAtoA(Bitmap bitmap) {
1477428a933c89e2d49036a1854143d5c28078fec75Tim Murray        Type.Builder tb_a8 = new Type.Builder(sRS, Element.A_8(sRS));
148575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        ScriptC_grey greyConvert = new ScriptC_grey(sRS,
149575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                sRS.getApplicationContext().getResources(), R.raw.grey);
150a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
15196df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Allocation bitmapTemp = convertBitmap(bitmap);
1527428a933c89e2d49036a1854143d5c28078fec75Tim Murray        if (bitmapTemp.getType().getElement().isCompatible(Element.A_8(sRS))) {
153a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray            return bitmapTemp;
154a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        }
155a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
156a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        tb_a8.setX(bitmapTemp.getType().getX());
157a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        tb_a8.setY(bitmapTemp.getType().getY());
158575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        Allocation bitmapAlloc = Allocation.createTyped(sRS, tb_a8.create());
159a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        greyConvert.forEach_RGBAtoA(bitmapTemp, bitmapAlloc);
160a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
161a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray        return bitmapAlloc;
1627706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    }
163a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
16496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    public Allocation loadResourceAlpha(int resource) {
165575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        Resources res = null;
166575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        synchronized(ImageFilterRS.class) {
167575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            res = sRS.getApplicationContext().getResources();
168575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        }
16996df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        final BitmapFactory.Options options = new BitmapFactory.Options();
17096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        options.inPreferredConfig = Bitmap.Config.ALPHA_8;
17196df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Bitmap bitmap = BitmapFactory.decodeResource(
172575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                res,
17396df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard                resource, options);
17496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Allocation ret = convertRGBAtoA(bitmap);
17596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        bitmap.recycle();
17696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        return ret;
17796df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    }
17896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard
17996df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    public Allocation loadResource(int resource) {
180575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        Resources res = null;
181575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        synchronized(ImageFilterRS.class) {
182575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk            res = sRS.getApplicationContext().getResources();
183575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk        }
18496df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        final BitmapFactory.Options options = new BitmapFactory.Options();
18596df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
18696df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Bitmap bitmap = BitmapFactory.decodeResource(
187575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk                res,
18896df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard                resource, options);
18996df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        Allocation ret = convertBitmap(bitmap);
19096df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        bitmap.recycle();
19196df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard        return ret;
19296df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard    }
19396df19b2a4b7286a01aeb690a38d8c99bc43449cnicolasroard
194575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private boolean isResourcesLoaded() {
1957706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        return mResourcesLoaded;
196a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray    }
197a7723fb08098c0c7682b02cf459cafa3792a4ce4Tim Murray
198575ce6f72fd87a62af1686edb3f17c0041031b86Ruben Brunk    private void setResourcesLoaded(boolean resourcesLoaded) {
1997706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        mResourcesLoaded = resourcesLoaded;
2007706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    }
2017706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard
202f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk    /**
203f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     *  Bitmaps and RS Allocations should be cleared here
204f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     */
2057706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    abstract protected void resetAllocations();
2067706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard
207f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk    /**
208f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     * RS Script objects (and all other RS objects) should be cleared here
209f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk     */
210f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk    abstract protected void resetScripts();
211f79f954f4eb23bce55061c683a07fc7b3a965451Ruben Brunk
2127706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    public void freeResources() {
2137706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        if (!isResourcesLoaded()) {
2147706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard            return;
2157706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard        }
216ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk        synchronized(ImageFilterRS.class) {
217ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk            resetAllocations();
218ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk            setResourcesLoaded(false);
219ea5355e6aa782bb61fbf079f4811873a67a83808Ruben Brunk        }
2207706e506dc74fa634a69b9ce8c7e5e2c457f01fcnicolasroard    }
2215448bf8095483574649afcc2add7f153670c7450nicolasroard}
222