Home | History | Annotate | Download | only in filters
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.gallery3d.photoeditor.filters;
     18 
     19 import android.media.effect.Effect;
     20 import android.media.effect.EffectContext;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 
     24 import com.android.gallery3d.photoeditor.Photo;
     25 
     26 import java.util.HashMap;
     27 
     28 /**
     29  * Image filter for photo editing; most of its methods must be called from a single GL thread except
     30  * validate()/isValid() that are called from UI thread.
     31  */
     32 public abstract class Filter implements Parcelable {
     33 
     34     // TODO: This should be set in MFF instead.
     35     private static final int DEFAULT_TILE_SIZE = 640;
     36 
     37     private static final HashMap<Filter, Effect> effects = new HashMap<Filter, Effect>();
     38     private static EffectContext context;
     39 
     40     private boolean isValid;
     41 
     42     /**
     43      * Filter context should be released before the current GL context is lost.
     44      */
     45     public static void releaseContext() {
     46         if (context != null) {
     47             // Release all effects created with the releasing context.
     48             for (Effect effect : effects.values()) {
     49                 effect.release();
     50             }
     51             effects.clear();
     52             context.release();
     53             context = null;
     54         }
     55     }
     56 
     57     public void release() {
     58         Effect effect = effects.remove(this);
     59         if (effect != null) {
     60             effect.release();
     61         }
     62     }
     63 
     64     protected Effect getEffect(String name) {
     65         Effect effect = effects.get(this);
     66         if (effect == null) {
     67             if (context == null) {
     68                 context = EffectContext.createWithCurrentGlContext();
     69             }
     70             effect = context.getFactory().createEffect(name);
     71             effect.setParameter("tile_size", DEFAULT_TILE_SIZE);
     72             effects.put(this, effect);
     73         }
     74         return effect;
     75     }
     76 
     77     protected void validate() {
     78         isValid = true;
     79     }
     80 
     81     /**
     82      * Some filters, e.g. lighting filters, are initially invalid until set up with parameters while
     83      * others, e.g. Sepia or Posterize filters, are initially valid without parameters.
     84      */
     85     public boolean isValid() {
     86         return isValid;
     87     }
     88 
     89     /**
     90      * Processes the source bitmap and matrix and output the destination bitmap and matrix.
     91      *
     92      * @param src source photo as the input.
     93      * @param dst destination photo having the same dimension as source photo as the output.
     94      */
     95     public abstract void process(Photo src, Photo dst);
     96 
     97     /**
     98      * Instantiates CREATOR of subclasses for Parcelable implementations.
     99      */
    100     protected static <T extends Filter> Parcelable.Creator<T> creatorOf(Class<T> filterClass) {
    101         return new FilterCreator<T>(filterClass);
    102     }
    103 
    104     /**
    105      * Saves states for restoring filter later; subclasses can override this to persist states.
    106      */
    107     protected void writeToParcel(Parcel out) {
    108     }
    109 
    110     /**
    111      * Restores filter from the saved states; subclasses can override this to persist states.
    112      */
    113     protected void readFromParcel(Parcel in) {
    114     }
    115 
    116     @Override
    117     public int describeContents() {
    118         return 0;
    119     }
    120 
    121     @Override
    122     public void writeToParcel(Parcel dest, int flags) {
    123         writeToParcel(dest);
    124     }
    125 }
    126