More native interpolators

 Gotta collect 'em all

Change-Id: I3ccc2b5c842b27b906c8a0470fbedc2bf285bc38
diff --git a/core/java/android/view/animation/AccelerateInterpolator.java b/core/java/android/view/animation/AccelerateInterpolator.java
index dcab743..c08f348 100644
--- a/core/java/android/view/animation/AccelerateInterpolator.java
+++ b/core/java/android/view/animation/AccelerateInterpolator.java
@@ -20,12 +20,17 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * An interpolator where the rate of change starts out slowly and 
  * and then accelerates.
  *
  */
-public class AccelerateInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class AccelerateInterpolator implements Interpolator, NativeInterpolatorFactory {
     private final float mFactor;
     private final double mDoubleFactor;
 
@@ -64,4 +69,10 @@
             return (float)Math.pow(input, mDoubleFactor);
         }
     }
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createAccelerateInterpolator(mFactor);
+    }
 }
diff --git a/core/java/android/view/animation/AnticipateInterpolator.java b/core/java/android/view/animation/AnticipateInterpolator.java
index a6f110e..83a8007 100644
--- a/core/java/android/view/animation/AnticipateInterpolator.java
+++ b/core/java/android/view/animation/AnticipateInterpolator.java
@@ -20,10 +20,15 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * An interpolator where the change starts backward then flings forward.
  */
-public class AnticipateInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class AnticipateInterpolator implements Interpolator, NativeInterpolatorFactory {
     private final float mTension;
 
     public AnticipateInterpolator() {
@@ -53,4 +58,10 @@
         // a(t) = t * t * ((tension + 1) * t - tension)
         return t * t * ((mTension + 1) * t - mTension);
     }
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createAnticipateInterpolator(mTension);
+    }
 }
diff --git a/core/java/android/view/animation/AnticipateOvershootInterpolator.java b/core/java/android/view/animation/AnticipateOvershootInterpolator.java
index 3dc9722..1a8adfd 100644
--- a/core/java/android/view/animation/AnticipateOvershootInterpolator.java
+++ b/core/java/android/view/animation/AnticipateOvershootInterpolator.java
@@ -19,6 +19,11 @@
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
+
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 import static com.android.internal.R.styleable.AnticipateOvershootInterpolator_extraTension;
 import static com.android.internal.R.styleable.AnticipateOvershootInterpolator_tension;
 import static com.android.internal.R.styleable.AnticipateOvershootInterpolator;
@@ -27,7 +32,8 @@
  * An interpolator where the change starts backward then flings forward and overshoots
  * the target value and finally goes back to the final value.
  */
-public class AnticipateOvershootInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class AnticipateOvershootInterpolator implements Interpolator, NativeInterpolatorFactory {
     private final float mTension;
 
     public AnticipateOvershootInterpolator() {
@@ -80,4 +86,10 @@
         if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
         else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
     }
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createAnticipateOvershootInterpolator(mTension);
+    }
 }
diff --git a/core/java/android/view/animation/BounceInterpolator.java b/core/java/android/view/animation/BounceInterpolator.java
index ecf99a7..9d8ca90 100644
--- a/core/java/android/view/animation/BounceInterpolator.java
+++ b/core/java/android/view/animation/BounceInterpolator.java
@@ -19,10 +19,15 @@
 import android.content.Context;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * An interpolator where the change bounces at the end.
  */
-public class BounceInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class BounceInterpolator implements Interpolator, NativeInterpolatorFactory {
     public BounceInterpolator() {
     }
 
@@ -47,4 +52,10 @@
         else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
         else return bounce(t - 1.0435f) + 0.95f;
     }
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createBounceInterpolator();
+    }
 }
\ No newline at end of file
diff --git a/core/java/android/view/animation/CycleInterpolator.java b/core/java/android/view/animation/CycleInterpolator.java
index d355c23..d1ebf05 100644
--- a/core/java/android/view/animation/CycleInterpolator.java
+++ b/core/java/android/view/animation/CycleInterpolator.java
@@ -20,12 +20,17 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * Repeats the animation for a specified number of cycles. The
  * rate of change follows a sinusoidal pattern.
  *
  */
-public class CycleInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class CycleInterpolator implements Interpolator, NativeInterpolatorFactory {
     public CycleInterpolator(float cycles) {
         mCycles = cycles;
     }
@@ -44,4 +49,10 @@
     }
     
     private float mCycles;
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createCycleInterpolator(mCycles);
+    }
 }
diff --git a/core/java/android/view/animation/DecelerateInterpolator.java b/core/java/android/view/animation/DecelerateInterpolator.java
index 20e079b..0789a0e 100644
--- a/core/java/android/view/animation/DecelerateInterpolator.java
+++ b/core/java/android/view/animation/DecelerateInterpolator.java
@@ -20,12 +20,17 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * An interpolator where the rate of change starts out quickly and 
  * and then decelerates.
  *
  */
-public class DecelerateInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class DecelerateInterpolator implements Interpolator, NativeInterpolatorFactory {
     public DecelerateInterpolator() {
     }
 
@@ -60,4 +65,10 @@
     }
     
     private float mFactor = 1.0f;
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createDecelerateInterpolator(mFactor);
+    }
 }
diff --git a/core/java/android/view/animation/LinearInterpolator.java b/core/java/android/view/animation/LinearInterpolator.java
index 96a039f..552c611 100644
--- a/core/java/android/view/animation/LinearInterpolator.java
+++ b/core/java/android/view/animation/LinearInterpolator.java
@@ -19,11 +19,16 @@
 import android.content.Context;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * An interpolator where the rate of change is constant
  *
  */
-public class LinearInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class LinearInterpolator implements Interpolator, NativeInterpolatorFactory {
 
     public LinearInterpolator() {
     }
@@ -34,4 +39,10 @@
     public float getInterpolation(float input) {
         return input;
     }
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
+    }
 }
diff --git a/core/java/android/view/animation/OvershootInterpolator.java b/core/java/android/view/animation/OvershootInterpolator.java
index 494f8ab..a2466f1 100644
--- a/core/java/android/view/animation/OvershootInterpolator.java
+++ b/core/java/android/view/animation/OvershootInterpolator.java
@@ -20,11 +20,16 @@
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
 
+import com.android.internal.view.animation.HasNativeInterpolator;
+import com.android.internal.view.animation.NativeInterpolatorFactory;
+import com.android.internal.view.animation.NativeInterpolatorFactoryHelper;
+
 /**
  * An interpolator where the change flings forward and overshoots the last value
  * then comes back.
  */
-public class OvershootInterpolator implements Interpolator {
+@HasNativeInterpolator
+public class OvershootInterpolator implements Interpolator, NativeInterpolatorFactory {
     private final float mTension;
 
     public OvershootInterpolator() {
@@ -56,4 +61,10 @@
         t -= 1.0f;
         return t * t * ((mTension + 1) * t + mTension) + 1.0f;
     }
+
+    /** @hide */
+    @Override
+    public long createNativeInterpolator() {
+        return NativeInterpolatorFactoryHelper.createOvershootInterpolator(mTension);
+    }
 }
diff --git a/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java b/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
index 2b25280..7cd75f3 100644
--- a/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
+++ b/core/java/com/android/internal/view/animation/NativeInterpolatorFactoryHelper.java
@@ -24,5 +24,13 @@
     private NativeInterpolatorFactoryHelper() {}
 
     public static native long createAccelerateDecelerateInterpolator();
+    public static native long createAccelerateInterpolator(float factor);
+    public static native long createAnticipateInterpolator(float tension);
+    public static native long createAnticipateOvershootInterpolator(float tension);
+    public static native long createBounceInterpolator();
+    public static native long createCycleInterpolator(float cycles);
+    public static native long createDecelerateInterpolator(float factor);
+    public static native long createLinearInterpolator();
+    public static native long createOvershootInterpolator(float tension);
     public static native long createLutInterpolator(float[] values);
 }
diff --git a/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp b/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
index c2d3dd1..704e1be 100644
--- a/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
+++ b/core/jni/com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
@@ -32,6 +32,38 @@
     return reinterpret_cast<jlong>(new AccelerateDecelerateInterpolator());
 }
 
+static jlong createAccelerateInterpolator(JNIEnv* env, jobject clazz, jfloat factor) {
+    return reinterpret_cast<jlong>(new AccelerateInterpolator(factor));
+}
+
+static jlong createAnticipateInterpolator(JNIEnv* env, jobject clazz, jfloat tension) {
+    return reinterpret_cast<jlong>(new AnticipateInterpolator(tension));
+}
+
+static jlong createAnticipateOvershootInterpolator(JNIEnv* env, jobject clazz, jfloat tension) {
+    return reinterpret_cast<jlong>(new AnticipateOvershootInterpolator(tension));
+}
+
+static jlong createBounceInterpolator(JNIEnv* env, jobject clazz) {
+    return reinterpret_cast<jlong>(new BounceInterpolator());
+}
+
+static jlong createCycleInterpolator(JNIEnv* env, jobject clazz, jfloat cycles) {
+    return reinterpret_cast<jlong>(new CycleInterpolator(cycles));
+}
+
+static jlong createDecelerateInterpolator(JNIEnv* env, jobject clazz, jfloat factor) {
+    return reinterpret_cast<jlong>(new DecelerateInterpolator(factor));
+}
+
+static jlong createLinearInterpolator(JNIEnv* env, jobject clazz) {
+    return reinterpret_cast<jlong>(new LinearInterpolator());
+}
+
+static jlong createOvershootInterpolator(JNIEnv* env, jobject clazz, jfloat tension) {
+    return reinterpret_cast<jlong>(new OvershootInterpolator(tension));
+}
+
 static jlong createLutInterpolator(JNIEnv* env, jobject clazz, jfloatArray jlut) {
     jsize len = env->GetArrayLength(jlut);
     if (len <= 0) {
@@ -53,6 +85,14 @@
 static JNINativeMethod gMethods[] = {
 #ifdef USE_OPENGL_RENDERER
     { "createAccelerateDecelerateInterpolator", "()J", (void*) createAccelerateDecelerateInterpolator },
+    { "createAccelerateInterpolator", "(F)J", (void*) createAccelerateInterpolator },
+    { "createAnticipateInterpolator", "(F)J", (void*) createAnticipateInterpolator },
+    { "createAnticipateOvershootInterpolator", "(F)J", (void*) createAnticipateOvershootInterpolator },
+    { "createBounceInterpolator", "()J", (void*) createBounceInterpolator },
+    { "createCycleInterpolator", "(F)J", (void*) createCycleInterpolator },
+    { "createDecelerateInterpolator", "(F)J", (void*) createDecelerateInterpolator },
+    { "createLinearInterpolator", "()J", (void*) createLinearInterpolator },
+    { "createOvershootInterpolator", "(F)J", (void*) createOvershootInterpolator },
     { "createLutInterpolator", "([F)J", (void*) createLutInterpolator },
 #endif
 };
diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp
index b56648e..1f84b86 100644
--- a/libs/hwui/Interpolator.cpp
+++ b/libs/hwui/Interpolator.cpp
@@ -18,7 +18,7 @@
 
 #include "Interpolator.h"
 
-#include <math.h>
+#include <cmath>
 #include <cutils/log.h>
 
 #include "utils/MathUtils.h"
@@ -34,6 +34,62 @@
     return (float)(cosf((input + 1) * M_PI) / 2.0f) + 0.5f;
 }
 
+float AccelerateInterpolator::interpolate(float input) {
+    if (mFactor == 1.0f) {
+        return input * input;
+    } else {
+        return pow(input, mDoubleFactor);
+    }
+}
+
+float AnticipateInterpolator::interpolate(float t) {
+    return t * t * ((mTension + 1) * t - mTension);
+}
+
+static float a(float t, float s) {
+    return t * t * ((s + 1) * t - s);
+}
+
+static float o(float t, float s) {
+    return t * t * ((s + 1) * t + s);
+}
+
+float AnticipateOvershootInterpolator::interpolate(float t) {
+    if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
+    else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
+}
+
+static float bounce(float t) {
+    return t * t * 8.0f;
+}
+
+float BounceInterpolator::interpolate(float t) {
+    t *= 1.1226f;
+    if (t < 0.3535f) return bounce(t);
+    else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
+    else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
+    else return bounce(t - 1.0435f) + 0.95f;
+}
+
+float CycleInterpolator::interpolate(float input) {
+    return sinf(2 * mCycles * M_PI * input);
+}
+
+float DecelerateInterpolator::interpolate(float input) {
+    float result;
+    if (mFactor == 1.0f) {
+        result = 1.0f - (1.0f - input) * (1.0f - input);
+    } else {
+        result = 1.0f - pow((1.0f - input), 2 * mFactor);
+    }
+    return result;
+}
+
+float OvershootInterpolator::interpolate(float t) {
+    t -= 1.0f;
+    return t * t * ((mTension + 1) * t + mTension) + 1.0f;
+}
+
 LUTInterpolator::LUTInterpolator(float* values, size_t size) {
     mValues = values;
     mSize = size;
diff --git a/libs/hwui/Interpolator.h b/libs/hwui/Interpolator.h
index 44fb37c..dfa0a85 100644
--- a/libs/hwui/Interpolator.h
+++ b/libs/hwui/Interpolator.h
@@ -37,12 +37,68 @@
 
 class ANDROID_API AccelerateDecelerateInterpolator : public Interpolator {
 public:
-    AccelerateDecelerateInterpolator() {}
-    virtual ~AccelerateDecelerateInterpolator() {}
-
     virtual float interpolate(float input);
 };
 
+class ANDROID_API AccelerateInterpolator : public Interpolator {
+public:
+    AccelerateInterpolator(float factor) : mFactor(factor), mDoubleFactor(factor*2) {}
+    virtual float interpolate(float input);
+private:
+    const float mFactor;
+    const float mDoubleFactor;
+};
+
+class ANDROID_API AnticipateInterpolator : public Interpolator {
+public:
+    AnticipateInterpolator(float tension) : mTension(tension) {}
+    virtual float interpolate(float input);
+private:
+    const float mTension;
+};
+
+class ANDROID_API AnticipateOvershootInterpolator : public Interpolator {
+public:
+    AnticipateOvershootInterpolator(float tension) : mTension(tension) {}
+    virtual float interpolate(float input);
+private:
+    const float mTension;
+};
+
+class ANDROID_API BounceInterpolator : public Interpolator {
+public:
+    virtual float interpolate(float input);
+};
+
+class ANDROID_API CycleInterpolator : public Interpolator {
+public:
+    CycleInterpolator(float cycles) : mCycles(cycles) {}
+    virtual float interpolate(float input);
+private:
+    const float mCycles;
+};
+
+class ANDROID_API DecelerateInterpolator : public Interpolator {
+public:
+    DecelerateInterpolator(float factor) : mFactor(factor) {}
+    virtual float interpolate(float input);
+private:
+    const float mFactor;
+};
+
+class ANDROID_API LinearInterpolator : public Interpolator {
+public:
+    virtual float interpolate(float input) { return input; }
+};
+
+class ANDROID_API OvershootInterpolator : public Interpolator {
+public:
+    OvershootInterpolator(float tension) : mTension(tension) {}
+    virtual float interpolate(float input);
+private:
+    const float mTension;
+};
+
 class ANDROID_API LUTInterpolator : public Interpolator {
 public:
     LUTInterpolator(float* values, size_t size);