ImageFilterRS.java revision b17b1b0758799914fbad5f4a3afae71ce58891fc
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;
21a64051696e46fb5d5e1c76e53ac95a4feba18585Tim Murrayimport android.support.v8.renderscript.*;
225448bf8095483574649afcc2add7f153670c7450nicolasroardimport android.util.Log;
235448bf8095483574649afcc2add7f153670c7450nicolasroard
244e6c07b71b269ee3fe7f6fa455bc540238df9dedJohn Hofordpublic abstract class ImageFilterRS extends ImageFilter {
255448bf8095483574649afcc2add7f153670c7450nicolasroard    private final String LOGTAG = "ImageFilterRS";
265448bf8095483574649afcc2add7f153670c7450nicolasroard
275448bf8095483574649afcc2add7f153670c7450nicolasroard    private static RenderScript mRS = null;
285448bf8095483574649afcc2add7f153670c7450nicolasroard    protected static Allocation mInPixelsAllocation;
295448bf8095483574649afcc2add7f153670c7450nicolasroard    protected static Allocation mOutPixelsAllocation;
305448bf8095483574649afcc2add7f153670c7450nicolasroard    private static android.content.res.Resources mResources = null;
3157eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard    private static Bitmap sOldBitmap = null;
3257eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard    private Bitmap mOldBitmap = null;
335448bf8095483574649afcc2add7f153670c7450nicolasroard
3457eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard    private final Bitmap.Config mBitmapConfig = Bitmap.Config.ARGB_8888;
3557eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard
36b01a32825018cfb79f2c965c1c3e3e25b5131229nicolasroard    public void resetBitmap() {
37b01a32825018cfb79f2c965c1c3e3e25b5131229nicolasroard        mOldBitmap = null;
38b01a32825018cfb79f2c965c1c3e3e25b5131229nicolasroard    }
39b01a32825018cfb79f2c965c1c3e3e25b5131229nicolasroard
4099baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford    public void prepare(Bitmap bitmap, float scaleFactor, int quality) {
4157eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard        if (sOldBitmap == null
4257eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard                || (bitmap.getWidth() != sOldBitmap.getWidth())
4357eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard                || (bitmap.getHeight() != sOldBitmap.getHeight())) {
4457eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            if (mInPixelsAllocation != null) {
4557eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard                mInPixelsAllocation.destroy();
460f8047fe826a84829ab37bc7cd24c8a4dea0db64Ruben Brunk                mInPixelsAllocation = null;
4757eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            }
4857eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            if (mOutPixelsAllocation != null) {
4957eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard                mOutPixelsAllocation.destroy();
500f8047fe826a84829ab37bc7cd24c8a4dea0db64Ruben Brunk                mOutPixelsAllocation = null;
5157eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            }
5257eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            Bitmap bitmapBuffer = bitmap.copy(mBitmapConfig, true);
533df4f831396ffbc11e4bbee0b6150794e8e44e0bnicolasroard            mOutPixelsAllocation = Allocation.createFromBitmap(mRS, bitmapBuffer,
543df4f831396ffbc11e4bbee0b6150794e8e44e0bnicolasroard                    Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
5557eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            mInPixelsAllocation = Allocation.createTyped(mRS,
5657eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard                    mOutPixelsAllocation.getType());
5757eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            sOldBitmap = bitmap;
5863a7dac01d394523799939596b960cb03321798dJohn Hoford        }
5957eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard        mInPixelsAllocation.copyFrom(bitmap);
6057eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard        if (mOldBitmap != sOldBitmap) {
6199baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford            createFilter(mResources, scaleFactor, quality);
6257eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard            mOldBitmap = sOldBitmap;
6363a7dac01d394523799939596b960cb03321798dJohn Hoford        }
645448bf8095483574649afcc2add7f153670c7450nicolasroard    }
655448bf8095483574649afcc2add7f153670c7450nicolasroard
6657eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard    public void createFilter(android.content.res.Resources res,
6799baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford            float scaleFactor, int quality) {
6857eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard        // Stub
695448bf8095483574649afcc2add7f153670c7450nicolasroard    }
705448bf8095483574649afcc2add7f153670c7450nicolasroard
715448bf8095483574649afcc2add7f153670c7450nicolasroard    public void runFilter() {
7257eedfd99676913f575b1f76e3a874026d1ddf7cnicolasroard        // Stub
735448bf8095483574649afcc2add7f153670c7450nicolasroard    }
745448bf8095483574649afcc2add7f153670c7450nicolasroard
755448bf8095483574649afcc2add7f153670c7450nicolasroard    public void update(Bitmap bitmap) {
765448bf8095483574649afcc2add7f153670c7450nicolasroard        mOutPixelsAllocation.copyTo(bitmap);
775448bf8095483574649afcc2add7f153670c7450nicolasroard    }
785448bf8095483574649afcc2add7f153670c7450nicolasroard
7981eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard    @Override
8099baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford    public Bitmap apply(Bitmap bitmap, float scaleFactor, int quality) {
815448bf8095483574649afcc2add7f153670c7450nicolasroard        if (bitmap == null) {
8281eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard            return bitmap;
835448bf8095483574649afcc2add7f153670c7450nicolasroard        }
845448bf8095483574649afcc2add7f153670c7450nicolasroard        try {
8599baf61387ab1ef15bb9db5fa3b2b55591e87059John Hoford            prepare(bitmap, scaleFactor, quality);
865448bf8095483574649afcc2add7f153670c7450nicolasroard            runFilter();
875448bf8095483574649afcc2add7f153670c7450nicolasroard            update(bitmap);
885448bf8095483574649afcc2add7f153670c7450nicolasroard        } catch (android.renderscript.RSIllegalArgumentException e) {
895448bf8095483574649afcc2add7f153670c7450nicolasroard            Log.e(LOGTAG, "Illegal argument? " + e);
905448bf8095483574649afcc2add7f153670c7450nicolasroard        } catch (android.renderscript.RSRuntimeException e) {
915448bf8095483574649afcc2add7f153670c7450nicolasroard            Log.e(LOGTAG, "RS runtime exception ? " + e);
92b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk        } catch (java.lang.OutOfMemoryError e) {
93b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            // Many of the renderscript filters allocated large (>16Mb resources) in order to apply.
94b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            System.gc();
95b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            displayLowMemoryToast();
96b17b1b0758799914fbad5f4a3afae71ce58891fcRuben Brunk            Log.e(LOGTAG, "not enough memory for filter " + getName(), e);
975448bf8095483574649afcc2add7f153670c7450nicolasroard        }
9881eb9976f967d9b3faa1749a8ab29d1743cf347dnicolasroard        return bitmap;
995448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1005448bf8095483574649afcc2add7f153670c7450nicolasroard
1015448bf8095483574649afcc2add7f153670c7450nicolasroard    public static RenderScript getRenderScriptContext() {
1025448bf8095483574649afcc2add7f153670c7450nicolasroard        return mRS;
1035448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1045448bf8095483574649afcc2add7f153670c7450nicolasroard
1055448bf8095483574649afcc2add7f153670c7450nicolasroard    public static void setRenderScriptContext(Activity context) {
1067921e124d57759d6f0887a42ddc360d923e60cddTim Murray        if (mRS == null) {
1077921e124d57759d6f0887a42ddc360d923e60cddTim Murray            mRS = RenderScript.create(context);
1087921e124d57759d6f0887a42ddc360d923e60cddTim Murray        }
1095448bf8095483574649afcc2add7f153670c7450nicolasroard        mResources = context.getResources();
110588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        if (mInPixelsAllocation != null) {
111588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mInPixelsAllocation.destroy();
112588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mInPixelsAllocation = null;
113588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        }
114588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        if (mOutPixelsAllocation != null) {
115588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mOutPixelsAllocation.destroy();
116588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard            mOutPixelsAllocation = null;
117588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        }
118588c30c74178bc399b043a5401f0c1f93ae22378nicolasroard        sOldBitmap = null;
1195448bf8095483574649afcc2add7f153670c7450nicolasroard    }
1205448bf8095483574649afcc2add7f153670c7450nicolasroard
1215448bf8095483574649afcc2add7f153670c7450nicolasroard}
122