RenderNodeAnimator.java revision 315c329544d7c593d1072b071cbb92d9afe74021
1/* 2 * Copyright (C) 2014 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 17package android.view; 18 19import android.animation.TimeInterpolator; 20import android.graphics.Canvas; 21import android.graphics.CanvasProperty; 22import android.graphics.Paint; 23import android.util.SparseIntArray; 24import android.util.TimeUtils; 25 26import com.android.internal.util.VirtualRefBasePtr; 27import com.android.internal.view.animation.FallbackLUTInterpolator; 28import com.android.internal.view.animation.HasNativeInterpolator; 29import com.android.internal.view.animation.NativeInterpolatorFactory; 30 31import java.lang.ref.WeakReference; 32 33/** 34 * @hide 35 */ 36public final class RenderNodeAnimator { 37 38 // Keep in sync with enum RenderProperty in Animator.h 39 public static final int TRANSLATION_X = 0; 40 public static final int TRANSLATION_Y = 1; 41 public static final int TRANSLATION_Z = 2; 42 public static final int SCALE_X = 3; 43 public static final int SCALE_Y = 4; 44 public static final int ROTATION = 5; 45 public static final int ROTATION_X = 6; 46 public static final int ROTATION_Y = 7; 47 public static final int X = 8; 48 public static final int Y = 9; 49 public static final int Z = 10; 50 public static final int ALPHA = 11; 51 52 // Keep in sync with enum PaintFields in Animator.h 53 public static final int PAINT_STROKE_WIDTH = 0; 54 public static final int PAINT_ALPHA = 1; 55 56 // ViewPropertyAnimator uses a mask for its values, we need to remap them 57 // to the enum values here. RenderPropertyAnimator can't use the mask values 58 // directly as internally it uses a lookup table so it needs the values to 59 // be sequential starting from 0 60 private static final SparseIntArray sViewPropertyAnimatorMap = new SparseIntArray(15) {{ 61 put(ViewPropertyAnimator.TRANSLATION_X, TRANSLATION_X); 62 put(ViewPropertyAnimator.TRANSLATION_Y, TRANSLATION_Y); 63 put(ViewPropertyAnimator.TRANSLATION_Z, TRANSLATION_Z); 64 put(ViewPropertyAnimator.SCALE_X, SCALE_X); 65 put(ViewPropertyAnimator.SCALE_Y, SCALE_Y); 66 put(ViewPropertyAnimator.ROTATION, ROTATION); 67 put(ViewPropertyAnimator.ROTATION_X, ROTATION_X); 68 put(ViewPropertyAnimator.ROTATION_Y, ROTATION_Y); 69 put(ViewPropertyAnimator.X, X); 70 put(ViewPropertyAnimator.Y, Y); 71 put(ViewPropertyAnimator.Z, Z); 72 put(ViewPropertyAnimator.ALPHA, ALPHA); 73 }}; 74 75 // Keep in sync DeltaValueType in Animator.h 76 public static final int DELTA_TYPE_ABSOLUTE = 0; 77 public static final int DELTA_TYPE_DELTA = 1; 78 79 private VirtualRefBasePtr mNativePtr; 80 81 private RenderNode mTarget; 82 private TimeInterpolator mInterpolator; 83 private boolean mStarted = false; 84 85 public int mapViewPropertyToRenderProperty(int viewProperty) { 86 return sViewPropertyAnimatorMap.get(viewProperty); 87 } 88 89 public RenderNodeAnimator(int property, int deltaType, float deltaValue) { 90 init(nCreateAnimator(new WeakReference<RenderNodeAnimator>(this), 91 property, deltaType, deltaValue)); 92 } 93 94 public RenderNodeAnimator(CanvasProperty<Float> property, int deltaType, float deltaValue) { 95 init(nCreateCanvasPropertyFloatAnimator( 96 new WeakReference<RenderNodeAnimator>(this), 97 property.getNativeContainer(), deltaType, deltaValue)); 98 } 99 100 public RenderNodeAnimator(CanvasProperty<Paint> property, int paintField, 101 int deltaType, float deltaValue) { 102 init(nCreateCanvasPropertyPaintAnimator( 103 new WeakReference<RenderNodeAnimator>(this), 104 property.getNativeContainer(), paintField, deltaType, deltaValue)); 105 } 106 107 private void init(long ptr) { 108 mNativePtr = new VirtualRefBasePtr(ptr); 109 } 110 111 private void checkMutable() { 112 if (mStarted) { 113 throw new IllegalStateException("Animator has already started, cannot change it now!"); 114 } 115 } 116 117 private void applyInterpolator() { 118 if (mInterpolator == null) return; 119 120 long ni; 121 if (mInterpolator.getClass().isAnnotationPresent(HasNativeInterpolator.class)) { 122 ni = ((NativeInterpolatorFactory)mInterpolator).createNativeInterpolator(); 123 } else { 124 int duration = nGetDuration(mNativePtr.get()); 125 ni = FallbackLUTInterpolator.createNativeInterpolator(mInterpolator, duration); 126 } 127 nSetInterpolator(mNativePtr.get(), ni); 128 } 129 130 private void start(RenderNode node) { 131 if (mStarted) { 132 throw new IllegalStateException("Already started!"); 133 } 134 mStarted = true; 135 applyInterpolator(); 136 mTarget = node; 137 mTarget.addAnimator(this); 138 } 139 140 public void start(View target) { 141 start(target.mRenderNode); 142 // Kick off a frame to start the process 143 target.invalidateViewProperty(true, false); 144 } 145 146 public void start(Canvas canvas) { 147 if (!(canvas instanceof GLES20RecordingCanvas)) { 148 throw new IllegalArgumentException("Not a GLES20RecordingCanvas"); 149 } 150 GLES20RecordingCanvas recordingCanvas = (GLES20RecordingCanvas) canvas; 151 start(recordingCanvas.mNode); 152 } 153 154 public void cancel() { 155 mTarget.removeAnimator(this); 156 } 157 158 public void setDuration(int duration) { 159 checkMutable(); 160 nSetDuration(mNativePtr.get(), duration); 161 } 162 163 public void setInterpolator(TimeInterpolator interpolator) { 164 checkMutable(); 165 mInterpolator = interpolator; 166 } 167 168 long getNativeAnimator() { 169 return mNativePtr.get(); 170 } 171 172 private void onFinished() { 173 mTarget.removeAnimator(this); 174 } 175 176 // Called by native 177 private static void callOnFinished(WeakReference<RenderNodeAnimator> weakThis) { 178 RenderNodeAnimator animator = weakThis.get(); 179 if (animator != null) { 180 animator.onFinished(); 181 } 182 } 183 184 private static native long nCreateAnimator(WeakReference<RenderNodeAnimator> weakThis, 185 int property, int deltaValueType, float deltaValue); 186 private static native long nCreateCanvasPropertyFloatAnimator(WeakReference<RenderNodeAnimator> weakThis, 187 long canvasProperty, int deltaValueType, float deltaValue); 188 private static native long nCreateCanvasPropertyPaintAnimator(WeakReference<RenderNodeAnimator> weakThis, 189 long canvasProperty, int paintField, int deltaValueType, float deltaValue); 190 private static native void nSetDuration(long nativePtr, int duration); 191 private static native int nGetDuration(long nativePtr); 192 private static native void nSetInterpolator(long animPtr, long interpolatorPtr); 193} 194