Merge "Add TimeInterpolator support to RNA"
This commit is contained in:
@@ -245,6 +245,9 @@ public class TimeUtils {
|
||||
private static final int SECONDS_PER_HOUR = 60 * 60;
|
||||
private static final int SECONDS_PER_DAY = 24 * 60 * 60;
|
||||
|
||||
/** @hide */
|
||||
public static final long NANOS_PER_MS = 1000000;
|
||||
|
||||
private static final Object sFormatSync = new Object();
|
||||
private static char[] sFormatStr = new char[HUNDRED_DAY_FIELD_LEN+5];
|
||||
|
||||
|
||||
@@ -112,8 +112,6 @@ public final class Choreographer {
|
||||
private static final int SKIPPED_FRAME_WARNING_LIMIT = SystemProperties.getInt(
|
||||
"debug.choreographer.skipwarning", 30);
|
||||
|
||||
private static final long NANOS_PER_MS = 1000000;
|
||||
|
||||
private static final int MSG_DO_FRAME = 0;
|
||||
private static final int MSG_DO_SCHEDULE_VSYNC = 1;
|
||||
private static final int MSG_DO_SCHEDULE_CALLBACK = 2;
|
||||
@@ -263,7 +261,7 @@ public final class Choreographer {
|
||||
* @return The refresh rate as the nanoseconds between frames
|
||||
* @hide
|
||||
*/
|
||||
long getFrameIntervalNanos() {
|
||||
public long getFrameIntervalNanos() {
|
||||
return mFrameIntervalNanos;
|
||||
}
|
||||
|
||||
@@ -456,7 +454,7 @@ public final class Choreographer {
|
||||
* @hide
|
||||
*/
|
||||
public long getFrameTime() {
|
||||
return getFrameTimeNanos() / NANOS_PER_MS;
|
||||
return getFrameTimeNanos() / TimeUtils.NANOS_PER_MS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -497,7 +495,7 @@ public final class Choreographer {
|
||||
}
|
||||
} else {
|
||||
final long nextFrameTime = Math.max(
|
||||
mLastFrameTimeNanos / NANOS_PER_MS + sFrameDelay, now);
|
||||
mLastFrameTimeNanos / TimeUtils.NANOS_PER_MS + sFrameDelay, now);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Scheduling next frame in " + (nextFrameTime - now) + " ms.");
|
||||
}
|
||||
@@ -746,7 +744,7 @@ public final class Choreographer {
|
||||
mFrame = frame;
|
||||
Message msg = Message.obtain(mHandler, this);
|
||||
msg.setAsynchronous(true);
|
||||
mHandler.sendMessageAtTime(msg, timestampNanos / NANOS_PER_MS);
|
||||
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,12 +16,17 @@
|
||||
|
||||
package android.view;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.CanvasProperty;
|
||||
import android.graphics.Paint;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.TimeUtils;
|
||||
|
||||
import com.android.internal.util.VirtualRefBasePtr;
|
||||
import com.android.internal.view.animation.FallbackLUTInterpolator;
|
||||
import com.android.internal.view.animation.HasNativeInterpolator;
|
||||
import com.android.internal.view.animation.NativeInterpolatorFactory;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
@@ -71,9 +76,12 @@ public final class RenderNodeAnimator {
|
||||
public static final int DELTA_TYPE_ABSOLUTE = 0;
|
||||
public static final int DELTA_TYPE_DELTA = 1;
|
||||
|
||||
private RenderNode mTarget;
|
||||
private VirtualRefBasePtr mNativePtr;
|
||||
|
||||
private RenderNode mTarget;
|
||||
private TimeInterpolator mInterpolator;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public int mapViewPropertyToRenderProperty(int viewProperty) {
|
||||
return sViewPropertyAnimatorMap.get(viewProperty);
|
||||
}
|
||||
@@ -100,9 +108,37 @@ public final class RenderNodeAnimator {
|
||||
mNativePtr = new VirtualRefBasePtr(ptr);
|
||||
}
|
||||
|
||||
public void start(View target) {
|
||||
mTarget = target.mRenderNode;
|
||||
private void checkMutable() {
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Animator has already started, cannot change it now!");
|
||||
}
|
||||
}
|
||||
|
||||
private void applyInterpolator() {
|
||||
if (mInterpolator == null) return;
|
||||
|
||||
long ni;
|
||||
if (mInterpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class)) {
|
||||
ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator();
|
||||
} else {
|
||||
int duration = nGetDuration(mNativePtr.get());
|
||||
ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration);
|
||||
}
|
||||
nSetInterpolator(mNativePtr.get(), ni);
|
||||
}
|
||||
|
||||
private void start(RenderNode node) {
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Already started!");
|
||||
}
|
||||
mStarted = true;
|
||||
applyInterpolator();
|
||||
mTarget = node;
|
||||
mTarget.addAnimator(this);
|
||||
}
|
||||
|
||||
public void start(View target) {
|
||||
start(target.mRenderNode);
|
||||
// Kick off a frame to start the process
|
||||
target.invalidateViewProperty(true, false);
|
||||
}
|
||||
@@ -112,8 +148,7 @@ public final class RenderNodeAnimator {
|
||||
throw new IllegalArgumentException("Not a GLES20RecordingCanvas");
|
||||
}
|
||||
GLES20RecordingCanvas recordingCanvas = (GLES20RecordingCanvas) canvas;
|
||||
mTarget = recordingCanvas.mNode;
|
||||
mTarget.addAnimator(this);
|
||||
start(recordingCanvas.mNode);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
@@ -121,9 +156,15 @@ public final class RenderNodeAnimator {
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
checkMutable();
|
||||
nSetDuration(mNativePtr.get(), duration);
|
||||
}
|
||||
|
||||
public void setInterpolator(TimeInterpolator interpolator) {
|
||||
checkMutable();
|
||||
mInterpolator = interpolator;
|
||||
}
|
||||
|
||||
long getNativeAnimator() {
|
||||
return mNativePtr.get();
|
||||
}
|
||||
@@ -147,4 +188,6 @@ public final class RenderNodeAnimator {
|
||||
private static native long nCreateCanvasPropertyPaintAnimator(WeakReference<RenderNodeAnimator> weakThis,
|
||||
long canvasProperty, int paintField, int deltaValueType, float deltaValue);
|
||||
private static native void nSetDuration(long nativePtr, int duration);
|
||||
private static native int nGetDuration(long nativePtr);
|
||||
private static native void nSetInterpolator(long animPtr, long interpolatorPtr);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Trace;
|
||||
import android.util.TimeUtils;
|
||||
import android.view.Surface.OutOfResourcesException;
|
||||
import android.view.View.AttachInfo;
|
||||
|
||||
@@ -51,8 +52,6 @@ public class ThreadedRenderer extends HardwareRenderer {
|
||||
|
||||
private static final Rect NULL_RECT = new Rect();
|
||||
|
||||
private static final long NANOS_PER_MS = 1000000;
|
||||
|
||||
// Keep in sync with DrawFrameTask.h SYNC_* flags
|
||||
// Nothing interesting to report
|
||||
private static final int SYNC_OK = 0x0;
|
||||
@@ -203,7 +202,7 @@ public class ThreadedRenderer extends HardwareRenderer {
|
||||
void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
|
||||
attachInfo.mIgnoreDirtyState = true;
|
||||
long frameTimeNanos = mChoreographer.getFrameTimeNanos();
|
||||
attachInfo.mDrawingTime = frameTimeNanos / NANOS_PER_MS;
|
||||
attachInfo.mDrawingTime = frameTimeNanos / TimeUtils.NANOS_PER_MS;
|
||||
|
||||
updateRootDisplayList(view, callbacks);
|
||||
|
||||
|
||||
@@ -19,12 +19,17 @@ package android.view.animation;
|
||||
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 starts and ends slowly but
|
||||
* accelerates through the middle.
|
||||
*
|
||||
*/
|
||||
public class AccelerateDecelerateInterpolator implements Interpolator {
|
||||
@HasNativeInterpolator
|
||||
public class AccelerateDecelerateInterpolator implements Interpolator, NativeInterpolatorFactory {
|
||||
public AccelerateDecelerateInterpolator() {
|
||||
}
|
||||
|
||||
@@ -35,4 +40,10 @@ public class AccelerateDecelerateInterpolator implements Interpolator {
|
||||
public float getInterpolation(float input) {
|
||||
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.util.TimeUtils;
|
||||
import android.view.Choreographer;
|
||||
|
||||
/**
|
||||
* Interpolator that builds a lookup table to use. This is a fallback for
|
||||
* building a native interpolator from a TimeInterpolator that is not marked
|
||||
* with {@link HasNativeInterpolator}
|
||||
*/
|
||||
@HasNativeInterpolator
|
||||
public class FallbackLUTInterpolator implements NativeInterpolatorFactory {
|
||||
|
||||
private final float mLut[];
|
||||
|
||||
/**
|
||||
* Used to cache the float[] LUT for use across multiple native
|
||||
* interpolator creation
|
||||
*/
|
||||
public FallbackLUTInterpolator(TimeInterpolator interpolator, int duration) {
|
||||
mLut = createLUT(interpolator, duration);
|
||||
}
|
||||
|
||||
private static float[] createLUT(TimeInterpolator interpolator, int duration) {
|
||||
long frameIntervalNanos = Choreographer.getInstance().getFrameIntervalNanos();
|
||||
int animIntervalMs = (int) (frameIntervalNanos / TimeUtils.NANOS_PER_MS);
|
||||
int numAnimFrames = (int) Math.ceil(duration / animIntervalMs);
|
||||
float values[] = new float[numAnimFrames];
|
||||
float lastFrame = numAnimFrames - 1;
|
||||
for (int i = 0; i < numAnimFrames; i++) {
|
||||
float inValue = i / lastFrame;
|
||||
values[i] = interpolator.getInterpolation(inValue);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long createNativeInterpolator() {
|
||||
return NativeInterpolatorFactoryHelper.createLutInterpolator(mLut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to create a one-shot float[] LUT & native interpolator
|
||||
*/
|
||||
public static long createNativeInterpolator(TimeInterpolator interpolator, int duration) {
|
||||
float[] lut = createLUT(interpolator, duration);
|
||||
return NativeInterpolatorFactoryHelper.createLutInterpolator(lut);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This is a class annotation that signals that it is safe to create
|
||||
* a native interpolator counterpart via {@link NativeInterpolatorFactory}
|
||||
*
|
||||
* The idea here is to prevent subclasses of interpolators from being treated as a
|
||||
* NativeInterpolatorFactory, and instead have them fall back to the LUT & LERP
|
||||
* method like a custom interpolator.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public @interface HasNativeInterpolator {
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
|
||||
public interface NativeInterpolatorFactory {
|
||||
long createNativeInterpolator();
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.view.animation;
|
||||
|
||||
/**
|
||||
* Static utility class for constructing native interpolators to keep the
|
||||
* JNI simpler
|
||||
*/
|
||||
public final class NativeInterpolatorFactoryHelper {
|
||||
private NativeInterpolatorFactoryHelper() {}
|
||||
|
||||
public static native long createAccelerateDecelerateInterpolator();
|
||||
public static native long createLutInterpolator(float[] values);
|
||||
}
|
||||
@@ -156,7 +156,8 @@ LOCAL_SRC_FILES:= \
|
||||
android_animation_PropertyValuesHolder.cpp \
|
||||
com_android_internal_net_NetworkStatsFactory.cpp \
|
||||
com_android_internal_os_Zygote.cpp \
|
||||
com_android_internal_util_VirtualRefBasePtr.cpp
|
||||
com_android_internal_util_VirtualRefBasePtr.cpp \
|
||||
com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(JNI_H_INCLUDE) \
|
||||
|
||||
@@ -131,6 +131,7 @@ extern int register_android_view_Surface(JNIEnv* env);
|
||||
extern int register_android_view_SurfaceControl(JNIEnv* env);
|
||||
extern int register_android_view_SurfaceSession(JNIEnv* env);
|
||||
extern int register_android_view_TextureView(JNIEnv* env);
|
||||
extern int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv *env);
|
||||
extern int register_android_database_CursorWindow(JNIEnv* env);
|
||||
extern int register_android_database_SQLiteConnection(JNIEnv* env);
|
||||
extern int register_android_database_SQLiteGlobal(JNIEnv* env);
|
||||
@@ -1206,6 +1207,7 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_view_SurfaceControl),
|
||||
REG_JNI(register_android_view_SurfaceSession),
|
||||
REG_JNI(register_android_view_TextureView),
|
||||
REG_JNI(register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper),
|
||||
REG_JNI(register_com_google_android_gles_jni_EGLImpl),
|
||||
REG_JNI(register_com_google_android_gles_jni_GLImpl),
|
||||
REG_JNI(register_android_opengl_jni_EGL14),
|
||||
|
||||
@@ -132,6 +132,17 @@ static void setDuration(JNIEnv* env, jobject clazz, jlong animatorPtr, jint dura
|
||||
animator->setDuration(duration);
|
||||
}
|
||||
|
||||
static jint getDuration(JNIEnv* env, jobject clazz, jlong animatorPtr) {
|
||||
BaseAnimator* animator = reinterpret_cast<BaseAnimator*>(animatorPtr);
|
||||
return static_cast<jint>(animator->duration());
|
||||
}
|
||||
|
||||
static void setInterpolator(JNIEnv* env, jobject clazz, jlong animatorPtr, jlong interpolatorPtr) {
|
||||
BaseAnimator* animator = reinterpret_cast<BaseAnimator*>(animatorPtr);
|
||||
Interpolator* interpolator = reinterpret_cast<Interpolator*>(interpolatorPtr);
|
||||
animator->setInterpolator(interpolator);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -146,6 +157,8 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nCreateCanvasPropertyFloatAnimator", "(Ljava/lang/ref/WeakReference;JIF)J", (void*) createCanvasPropertyFloatAnimator },
|
||||
{ "nCreateCanvasPropertyPaintAnimator", "(Ljava/lang/ref/WeakReference;JIIF)J", (void*) createCanvasPropertyPaintAnimator },
|
||||
{ "nSetDuration", "(JI)V", (void*) setDuration },
|
||||
{ "nGetDuration", "(J)I", (void*) getDuration },
|
||||
{ "nSetInterpolator", "(JJ)V", (void*) setInterpolator },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "OpenGLRenderer"
|
||||
|
||||
#include "jni.h"
|
||||
#include <nativehelper/JNIHelp.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include <Interpolator.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
using namespace uirenderer;
|
||||
|
||||
#ifdef USE_OPENGL_RENDERER
|
||||
|
||||
static jlong createAccelerateDecelerateInterpolator(JNIEnv* env, jobject clazz) {
|
||||
return reinterpret_cast<jlong>(new AccelerateDecelerateInterpolator());
|
||||
}
|
||||
|
||||
static jlong createLutInterpolator(JNIEnv* env, jobject clazz, jfloatArray jlut) {
|
||||
jsize len = env->GetArrayLength(jlut);
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
float* lut = new float[len];
|
||||
env->GetFloatArrayRegion(jlut, 0, len, lut);
|
||||
return reinterpret_cast<jlong>(new LUTInterpolator(lut, len));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// JNI Glue
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
const char* const kClassPathName = "com/android/internal/view/animation/NativeInterpolatorFactoryHelper";
|
||||
|
||||
static JNINativeMethod gMethods[] = {
|
||||
#ifdef USE_OPENGL_RENDERER
|
||||
{ "createAccelerateDecelerateInterpolator", "()J", (void*) createAccelerateDecelerateInterpolator },
|
||||
{ "createLutInterpolator", "([F)J", (void*) createLutInterpolator },
|
||||
#endif
|
||||
};
|
||||
|
||||
int register_com_android_internal_view_animation_NativeInterpolatorFactoryHelper(JNIEnv* env) {
|
||||
return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
|
||||
}
|
||||
|
||||
|
||||
} // namespace android
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
|
||||
ANDROID_API void setInterpolator(Interpolator* interpolator);
|
||||
ANDROID_API void setDuration(nsecs_t durationInMs);
|
||||
ANDROID_API nsecs_t duration() { return mDuration; }
|
||||
ANDROID_API void setListener(AnimationListener* listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@@ -13,9 +13,15 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Interpolator"
|
||||
|
||||
#include "Interpolator.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include "utils/MathUtils.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
@@ -28,5 +34,34 @@ float AccelerateDecelerateInterpolator::interpolate(float input) {
|
||||
return (float)(cosf((input + 1) * M_PI) / 2.0f) + 0.5f;
|
||||
}
|
||||
|
||||
LUTInterpolator::LUTInterpolator(float* values, size_t size) {
|
||||
mValues = values;
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
LUTInterpolator::~LUTInterpolator() {
|
||||
delete mValues;
|
||||
mValues = 0;
|
||||
}
|
||||
|
||||
float LUTInterpolator::interpolate(float input) {
|
||||
float lutpos = input * mSize;
|
||||
if (lutpos >= (mSize - 1)) {
|
||||
return mValues[mSize - 1];
|
||||
}
|
||||
|
||||
float ipart, weight;
|
||||
weight = modff(lutpos, &ipart);
|
||||
|
||||
int i1 = (int) ipart;
|
||||
int i2 = MathUtils::min(i1 + 1, mSize - 1);
|
||||
|
||||
float v1 = mValues[i1];
|
||||
float v2 = mValues[i2];
|
||||
|
||||
return MathUtils::lerp(v1, v2, weight);
|
||||
}
|
||||
|
||||
|
||||
} /* namespace uirenderer */
|
||||
} /* namespace android */
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#ifndef INTERPOLATOR_H
|
||||
#define INTERPOLATOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
@@ -31,7 +35,7 @@ protected:
|
||||
Interpolator() {}
|
||||
};
|
||||
|
||||
class AccelerateDecelerateInterpolator : public Interpolator {
|
||||
class ANDROID_API AccelerateDecelerateInterpolator : public Interpolator {
|
||||
public:
|
||||
AccelerateDecelerateInterpolator() {}
|
||||
virtual ~AccelerateDecelerateInterpolator() {}
|
||||
@@ -39,6 +43,18 @@ public:
|
||||
virtual float interpolate(float input);
|
||||
};
|
||||
|
||||
class ANDROID_API LUTInterpolator : public Interpolator {
|
||||
public:
|
||||
LUTInterpolator(float* values, size_t size);
|
||||
~LUTInterpolator();
|
||||
|
||||
virtual float interpolate(float input);
|
||||
|
||||
private:
|
||||
float* mValues;
|
||||
size_t mSize;
|
||||
};
|
||||
|
||||
} /* namespace uirenderer */
|
||||
} /* namespace android */
|
||||
|
||||
|
||||
@@ -33,6 +33,14 @@ public:
|
||||
inline static bool isPositive(float value) {
|
||||
return value >= gNonZeroEpsilon;
|
||||
}
|
||||
|
||||
inline static int min(int a, int b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
inline static float lerp(float v1, float v2, float t) {
|
||||
return v1 + ((v2 - v1) * t);
|
||||
}
|
||||
}; // class MathUtils
|
||||
|
||||
} /* namespace uirenderer */
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.test.hwui;
|
||||
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
@@ -27,6 +28,8 @@ import android.os.Trace;
|
||||
import android.view.HardwareCanvas;
|
||||
import android.view.RenderNodeAnimator;
|
||||
import android.view.View;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
@@ -122,8 +125,11 @@ public class CirclePropActivity extends Activity {
|
||||
mPaint, RenderNodeAnimator.PAINT_STROKE_WIDTH,
|
||||
RenderNodeAnimator.DELTA_TYPE_ABSOLUTE, mToggle ? 5.0f : 60.0f));
|
||||
|
||||
TimeInterpolator interp = new OvershootInterpolator(3.0f);
|
||||
for (int i = 0; i < mRunningAnimations.size(); i++) {
|
||||
mRunningAnimations.get(i).start(this);
|
||||
RenderNodeAnimator anim = mRunningAnimations.get(i);
|
||||
anim.setInterpolator(interp);
|
||||
anim.start(this);
|
||||
}
|
||||
|
||||
if (mToggle) {
|
||||
|
||||
Reference in New Issue
Block a user