Loading core/java/android/view/Choreographer.java +1 −1 Original line number Diff line number Diff line Loading @@ -431,7 +431,7 @@ public final class Choreographer { /** * Gets the time when the current frame started. * <p> * This method provides the time in nanoseconds when the frame started being rendered. * This method provides the time in milliseconds when the frame started being rendered. * The frame time provides a stable time base for synchronizing animations * and drawing. It should be used instead of {@link SystemClock#uptimeMillis()} * or {@link System#nanoTime()} for animations and drawing in the UI. Using the frame Loading core/java/android/view/RenderNodeAnimator.java +31 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view; import android.animation.Animator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.graphics.Canvas; import android.graphics.CanvasProperty; import android.graphics.Paint; Loading @@ -34,7 +35,7 @@ import java.util.ArrayList; /** * @hide */ public final class RenderNodeAnimator extends Animator { public class RenderNodeAnimator extends Animator { // Keep in sync with enum RenderProperty in Animator.h public static final int TRANSLATION_X = 0; public static final int TRANSLATION_Y = 1; Loading Loading @@ -83,16 +84,23 @@ public final class RenderNodeAnimator extends Animator { private RenderNode mTarget; private View mViewTarget; private int mRenderProperty = -1; private float mFinalValue; private TimeInterpolator mInterpolator; private boolean mStarted = false; private boolean mFinished = false; private long mUnscaledDuration = 300; private long mUnscaledStartDelay = 0; public static int mapViewPropertyToRenderProperty(int viewProperty) { return sViewPropertyAnimatorMap.get(viewProperty); } public RenderNodeAnimator(int property, float finalValue) { mRenderProperty = property; mFinalValue = finalValue; init(nCreateAnimator(new WeakReference<RenderNodeAnimator>(this), property, finalValue)); } Loading Loading @@ -156,7 +164,16 @@ public final class RenderNodeAnimator extends Animator { mStarted = true; applyInterpolator(); mTarget.addAnimator(this); nStart(mNativePtr.get()); // Alpha is a special snowflake that has the canonical value stored // in mTransformationInfo instead of in RenderNode, so we need to update // it with the final value here. if (mRenderProperty == RenderNodeAnimator.ALPHA) { // Don't need null check because ViewPropertyAnimator's // ctor calls ensureTransformationInfo() mViewTarget.mTransformationInfo.mAlpha = mFinalValue; } final ArrayList<AnimatorListener> listeners = getListeners(); final int numListeners = listeners == null ? 0 : listeners.size(); Loading Loading @@ -201,6 +218,7 @@ public final class RenderNodeAnimator extends Animator { public void setTarget(View view) { mViewTarget = view; mTarget = view.mRenderNode; mTarget.addAnimator(this); } public void setTarget(Canvas canvas) { Loading @@ -213,12 +231,12 @@ public final class RenderNodeAnimator extends Animator { } public void setTarget(RenderNode node) { if (mTarget != null) { throw new IllegalStateException("Target already set!"); } mViewTarget = null; mTarget = node; } public RenderNode getTarget() { return mTarget; mTarget.addAnimator(this); } public void setStartValue(float startValue) { Loading @@ -232,12 +250,13 @@ public final class RenderNodeAnimator extends Animator { if (startDelay < 0) { throw new IllegalArgumentException("startDelay must be positive; " + startDelay); } nSetStartDelay(mNativePtr.get(), startDelay); mUnscaledStartDelay = startDelay; nSetStartDelay(mNativePtr.get(), (long) (startDelay * ValueAnimator.getDurationScale())); } @Override public long getStartDelay() { return nGetStartDelay(mNativePtr.get()); return mUnscaledStartDelay; } @Override Loading @@ -246,13 +265,14 @@ public final class RenderNodeAnimator extends Animator { if (duration < 0) { throw new IllegalArgumentException("duration must be positive; " + duration); } nSetDuration(mNativePtr.get(), duration); mUnscaledDuration = duration; nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale())); return this; } @Override public long getDuration() { return nGetDuration(mNativePtr.get()); return mUnscaledDuration; } @Override Loading Loading @@ -307,5 +327,6 @@ public final class RenderNodeAnimator extends Animator { private static native long nGetStartDelay(long nativePtr); private static native void nSetInterpolator(long animPtr, long interpolatorPtr); private static native void nStart(long animPtr); private static native void nCancel(long animPtr); } core/java/android/view/RenderNodeAnimatorCompat.java 0 → 100644 +144 −0 Original line number Diff line number Diff line /* * 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 android.view; import android.animation.ValueAnimator; import java.util.ArrayList; /** * This class provides compatibility for things like start listeners & * start delays for use by ViewPropertyAnimator and ObjectAnimator * @hide */ public class RenderNodeAnimatorCompat extends RenderNodeAnimator { private long mUnscaledStartDelay = 0; private long mStartDelay = 0; private long mStartTime; private boolean mCanceled; public RenderNodeAnimatorCompat(int property, float finalValue) { super(property, finalValue); } @Override public void setStartDelay(long startDelay) { mUnscaledStartDelay = startDelay; mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay); } @Override public long getStartDelay() { return mUnscaledStartDelay; } @Override public void start() { if (mStartDelay <= 0) { doStart(); } else { getHelper().addDelayedAnimation(this); } } private void doStart() { if (!mCanceled) { super.start(); } } @Override public void cancel() { mCanceled = true; super.cancel(); } /** * @return true if the animator was started, false if still delayed */ private boolean processDelayed(long frameTimeMs) { if (mCanceled) return true; if (mStartTime == 0) { mStartTime = frameTimeMs; } else if ((frameTimeMs - mStartTime) >= mStartDelay) { doStart(); return true; } return false; } private static AnimationHelper getHelper() { AnimationHelper helper = sAnimationHelper.get(); if (helper == null) { helper = new AnimationHelper(); sAnimationHelper.set(helper); } return helper; } private static ThreadLocal<AnimationHelper> sAnimationHelper = new ThreadLocal<AnimationHelper>(); private static class AnimationHelper implements Runnable { private ArrayList<RenderNodeAnimatorCompat> mDelayedAnims = new ArrayList<RenderNodeAnimatorCompat>(); private final Choreographer mChoreographer; private boolean mCallbackScheduled; public AnimationHelper() { mChoreographer = Choreographer.getInstance(); } public void addDelayedAnimation(RenderNodeAnimatorCompat animator) { mDelayedAnims.add(animator); scheduleCallback(); } private void scheduleCallback() { if (!mCallbackScheduled) { mCallbackScheduled = true; mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null); } } @Override public void run() { long frameTimeMs = mChoreographer.getFrameTime(); mCallbackScheduled = false; int end = 0; for (int i = 0; i < mDelayedAnims.size(); i++) { RenderNodeAnimatorCompat animator = mDelayedAnims.get(i); if (!animator.processDelayed(frameTimeMs)) { if (end != i) { mDelayedAnims.set(end, animator); } end++; } } while (mDelayedAnims.size() > end) { mDelayedAnims.remove(mDelayedAnims.size() - 1); } if (mDelayedAnims.size() > 0) { scheduleCallback(); } } } } core/java/android/view/ViewPropertyAnimatorRT.java +2 −9 Original line number Diff line number Diff line Loading @@ -81,21 +81,14 @@ class ViewPropertyAnimatorRT { int property = RenderNodeAnimator.mapViewPropertyToRenderProperty(holder.mNameConstant); final float finalValue = holder.mFromValue + holder.mDeltaValue; RenderNodeAnimator animator = new RenderNodeAnimator(property, finalValue); RenderNodeAnimator animator = new RenderNodeAnimatorCompat(property, finalValue); animator.setStartDelay(startDelay); animator.setDuration(duration); animator.setInterpolator(interpolator); animator.setTarget(mView); animator.start(); // Alpha is a special snowflake that has the canonical value stored // in mTransformationInfo instead of in RenderNode, so we need to update // it with the final value here. if (property == RenderNodeAnimator.ALPHA) { // Don't need null check because ViewPropertyAnimator's // ctor calls ensureTransformationInfo() parent.mView.mTransformationInfo.mAlpha = finalValue; } mAnimators[property] = animator; } parent.mPendingAnimations.clear(); Loading core/jni/android_view_RenderNode.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -456,7 +456,6 @@ static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz, RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr); renderNode->addAnimator(animator); animator->start(); } #endif // USE_OPENGL_RENDERER Loading Loading
core/java/android/view/Choreographer.java +1 −1 Original line number Diff line number Diff line Loading @@ -431,7 +431,7 @@ public final class Choreographer { /** * Gets the time when the current frame started. * <p> * This method provides the time in nanoseconds when the frame started being rendered. * This method provides the time in milliseconds when the frame started being rendered. * The frame time provides a stable time base for synchronizing animations * and drawing. It should be used instead of {@link SystemClock#uptimeMillis()} * or {@link System#nanoTime()} for animations and drawing in the UI. Using the frame Loading
core/java/android/view/RenderNodeAnimator.java +31 −10 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.view; import android.animation.Animator; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.graphics.Canvas; import android.graphics.CanvasProperty; import android.graphics.Paint; Loading @@ -34,7 +35,7 @@ import java.util.ArrayList; /** * @hide */ public final class RenderNodeAnimator extends Animator { public class RenderNodeAnimator extends Animator { // Keep in sync with enum RenderProperty in Animator.h public static final int TRANSLATION_X = 0; public static final int TRANSLATION_Y = 1; Loading Loading @@ -83,16 +84,23 @@ public final class RenderNodeAnimator extends Animator { private RenderNode mTarget; private View mViewTarget; private int mRenderProperty = -1; private float mFinalValue; private TimeInterpolator mInterpolator; private boolean mStarted = false; private boolean mFinished = false; private long mUnscaledDuration = 300; private long mUnscaledStartDelay = 0; public static int mapViewPropertyToRenderProperty(int viewProperty) { return sViewPropertyAnimatorMap.get(viewProperty); } public RenderNodeAnimator(int property, float finalValue) { mRenderProperty = property; mFinalValue = finalValue; init(nCreateAnimator(new WeakReference<RenderNodeAnimator>(this), property, finalValue)); } Loading Loading @@ -156,7 +164,16 @@ public final class RenderNodeAnimator extends Animator { mStarted = true; applyInterpolator(); mTarget.addAnimator(this); nStart(mNativePtr.get()); // Alpha is a special snowflake that has the canonical value stored // in mTransformationInfo instead of in RenderNode, so we need to update // it with the final value here. if (mRenderProperty == RenderNodeAnimator.ALPHA) { // Don't need null check because ViewPropertyAnimator's // ctor calls ensureTransformationInfo() mViewTarget.mTransformationInfo.mAlpha = mFinalValue; } final ArrayList<AnimatorListener> listeners = getListeners(); final int numListeners = listeners == null ? 0 : listeners.size(); Loading Loading @@ -201,6 +218,7 @@ public final class RenderNodeAnimator extends Animator { public void setTarget(View view) { mViewTarget = view; mTarget = view.mRenderNode; mTarget.addAnimator(this); } public void setTarget(Canvas canvas) { Loading @@ -213,12 +231,12 @@ public final class RenderNodeAnimator extends Animator { } public void setTarget(RenderNode node) { if (mTarget != null) { throw new IllegalStateException("Target already set!"); } mViewTarget = null; mTarget = node; } public RenderNode getTarget() { return mTarget; mTarget.addAnimator(this); } public void setStartValue(float startValue) { Loading @@ -232,12 +250,13 @@ public final class RenderNodeAnimator extends Animator { if (startDelay < 0) { throw new IllegalArgumentException("startDelay must be positive; " + startDelay); } nSetStartDelay(mNativePtr.get(), startDelay); mUnscaledStartDelay = startDelay; nSetStartDelay(mNativePtr.get(), (long) (startDelay * ValueAnimator.getDurationScale())); } @Override public long getStartDelay() { return nGetStartDelay(mNativePtr.get()); return mUnscaledStartDelay; } @Override Loading @@ -246,13 +265,14 @@ public final class RenderNodeAnimator extends Animator { if (duration < 0) { throw new IllegalArgumentException("duration must be positive; " + duration); } nSetDuration(mNativePtr.get(), duration); mUnscaledDuration = duration; nSetDuration(mNativePtr.get(), (long) (duration * ValueAnimator.getDurationScale())); return this; } @Override public long getDuration() { return nGetDuration(mNativePtr.get()); return mUnscaledDuration; } @Override Loading Loading @@ -307,5 +327,6 @@ public final class RenderNodeAnimator extends Animator { private static native long nGetStartDelay(long nativePtr); private static native void nSetInterpolator(long animPtr, long interpolatorPtr); private static native void nStart(long animPtr); private static native void nCancel(long animPtr); }
core/java/android/view/RenderNodeAnimatorCompat.java 0 → 100644 +144 −0 Original line number Diff line number Diff line /* * 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 android.view; import android.animation.ValueAnimator; import java.util.ArrayList; /** * This class provides compatibility for things like start listeners & * start delays for use by ViewPropertyAnimator and ObjectAnimator * @hide */ public class RenderNodeAnimatorCompat extends RenderNodeAnimator { private long mUnscaledStartDelay = 0; private long mStartDelay = 0; private long mStartTime; private boolean mCanceled; public RenderNodeAnimatorCompat(int property, float finalValue) { super(property, finalValue); } @Override public void setStartDelay(long startDelay) { mUnscaledStartDelay = startDelay; mStartDelay = (long) (ValueAnimator.getDurationScale() * startDelay); } @Override public long getStartDelay() { return mUnscaledStartDelay; } @Override public void start() { if (mStartDelay <= 0) { doStart(); } else { getHelper().addDelayedAnimation(this); } } private void doStart() { if (!mCanceled) { super.start(); } } @Override public void cancel() { mCanceled = true; super.cancel(); } /** * @return true if the animator was started, false if still delayed */ private boolean processDelayed(long frameTimeMs) { if (mCanceled) return true; if (mStartTime == 0) { mStartTime = frameTimeMs; } else if ((frameTimeMs - mStartTime) >= mStartDelay) { doStart(); return true; } return false; } private static AnimationHelper getHelper() { AnimationHelper helper = sAnimationHelper.get(); if (helper == null) { helper = new AnimationHelper(); sAnimationHelper.set(helper); } return helper; } private static ThreadLocal<AnimationHelper> sAnimationHelper = new ThreadLocal<AnimationHelper>(); private static class AnimationHelper implements Runnable { private ArrayList<RenderNodeAnimatorCompat> mDelayedAnims = new ArrayList<RenderNodeAnimatorCompat>(); private final Choreographer mChoreographer; private boolean mCallbackScheduled; public AnimationHelper() { mChoreographer = Choreographer.getInstance(); } public void addDelayedAnimation(RenderNodeAnimatorCompat animator) { mDelayedAnims.add(animator); scheduleCallback(); } private void scheduleCallback() { if (!mCallbackScheduled) { mCallbackScheduled = true; mChoreographer.postCallback(Choreographer.CALLBACK_ANIMATION, this, null); } } @Override public void run() { long frameTimeMs = mChoreographer.getFrameTime(); mCallbackScheduled = false; int end = 0; for (int i = 0; i < mDelayedAnims.size(); i++) { RenderNodeAnimatorCompat animator = mDelayedAnims.get(i); if (!animator.processDelayed(frameTimeMs)) { if (end != i) { mDelayedAnims.set(end, animator); } end++; } } while (mDelayedAnims.size() > end) { mDelayedAnims.remove(mDelayedAnims.size() - 1); } if (mDelayedAnims.size() > 0) { scheduleCallback(); } } } }
core/java/android/view/ViewPropertyAnimatorRT.java +2 −9 Original line number Diff line number Diff line Loading @@ -81,21 +81,14 @@ class ViewPropertyAnimatorRT { int property = RenderNodeAnimator.mapViewPropertyToRenderProperty(holder.mNameConstant); final float finalValue = holder.mFromValue + holder.mDeltaValue; RenderNodeAnimator animator = new RenderNodeAnimator(property, finalValue); RenderNodeAnimator animator = new RenderNodeAnimatorCompat(property, finalValue); animator.setStartDelay(startDelay); animator.setDuration(duration); animator.setInterpolator(interpolator); animator.setTarget(mView); animator.start(); // Alpha is a special snowflake that has the canonical value stored // in mTransformationInfo instead of in RenderNode, so we need to update // it with the final value here. if (property == RenderNodeAnimator.ALPHA) { // Don't need null check because ViewPropertyAnimator's // ctor calls ensureTransformationInfo() parent.mView.mTransformationInfo.mAlpha = finalValue; } mAnimators[property] = animator; } parent.mPendingAnimations.clear(); Loading
core/jni/android_view_RenderNode.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -456,7 +456,6 @@ static void android_view_RenderNode_addAnimator(JNIEnv* env, jobject clazz, RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr); RenderPropertyAnimator* animator = reinterpret_cast<RenderPropertyAnimator*>(animatorPtr); renderNode->addAnimator(animator); animator->start(); } #endif // USE_OPENGL_RENDERER Loading