1315c329544d7c593d1072b071cbb92d9afe74021John Reck/* 2315c329544d7c593d1072b071cbb92d9afe74021John Reck * Copyright (C) 2014 The Android Open Source Project 3315c329544d7c593d1072b071cbb92d9afe74021John Reck * 4315c329544d7c593d1072b071cbb92d9afe74021John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 5315c329544d7c593d1072b071cbb92d9afe74021John Reck * you may not use this file except in compliance with the License. 6315c329544d7c593d1072b071cbb92d9afe74021John Reck * You may obtain a copy of the License at 7315c329544d7c593d1072b071cbb92d9afe74021John Reck * 8315c329544d7c593d1072b071cbb92d9afe74021John Reck * http://www.apache.org/licenses/LICENSE-2.0 9315c329544d7c593d1072b071cbb92d9afe74021John Reck * 10315c329544d7c593d1072b071cbb92d9afe74021John Reck * Unless required by applicable law or agreed to in writing, software 11315c329544d7c593d1072b071cbb92d9afe74021John Reck * distributed under the License is distributed on an "AS IS" BASIS, 12315c329544d7c593d1072b071cbb92d9afe74021John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13315c329544d7c593d1072b071cbb92d9afe74021John Reck * See the License for the specific language governing permissions and 14315c329544d7c593d1072b071cbb92d9afe74021John Reck * limitations under the License. 15315c329544d7c593d1072b071cbb92d9afe74021John Reck */ 16315c329544d7c593d1072b071cbb92d9afe74021John Reck 17315c329544d7c593d1072b071cbb92d9afe74021John Reckpackage com.android.internal.view.animation; 18315c329544d7c593d1072b071cbb92d9afe74021John Reck 19315c329544d7c593d1072b071cbb92d9afe74021John Reckimport android.animation.TimeInterpolator; 20315c329544d7c593d1072b071cbb92d9afe74021John Reckimport android.util.TimeUtils; 21315c329544d7c593d1072b071cbb92d9afe74021John Reckimport android.view.Choreographer; 22315c329544d7c593d1072b071cbb92d9afe74021John Reck 23315c329544d7c593d1072b071cbb92d9afe74021John Reck/** 24315c329544d7c593d1072b071cbb92d9afe74021John Reck * Interpolator that builds a lookup table to use. This is a fallback for 25315c329544d7c593d1072b071cbb92d9afe74021John Reck * building a native interpolator from a TimeInterpolator that is not marked 26315c329544d7c593d1072b071cbb92d9afe74021John Reck * with {@link HasNativeInterpolator} 27918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck * 28918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck * This implements TimeInterpolator to allow for easier interop with Animators 29315c329544d7c593d1072b071cbb92d9afe74021John Reck */ 30315c329544d7c593d1072b071cbb92d9afe74021John Reck@HasNativeInterpolator 31918988c1ce5af002d41c7ac37f3fa490558b0c90John Reckpublic class FallbackLUTInterpolator implements NativeInterpolatorFactory, TimeInterpolator { 32315c329544d7c593d1072b071cbb92d9afe74021John Reck 33a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu // If the duration of an animation is more than 300 frames, we cap the sample size to 300. 34a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu private static final int MAX_SAMPLE_POINTS = 300; 35918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck private TimeInterpolator mSourceInterpolator; 36315c329544d7c593d1072b071cbb92d9afe74021John Reck private final float mLut[]; 37315c329544d7c593d1072b071cbb92d9afe74021John Reck 38315c329544d7c593d1072b071cbb92d9afe74021John Reck /** 39315c329544d7c593d1072b071cbb92d9afe74021John Reck * Used to cache the float[] LUT for use across multiple native 40315c329544d7c593d1072b071cbb92d9afe74021John Reck * interpolator creation 41315c329544d7c593d1072b071cbb92d9afe74021John Reck */ 42ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public FallbackLUTInterpolator(TimeInterpolator interpolator, long duration) { 43918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck mSourceInterpolator = interpolator; 44315c329544d7c593d1072b071cbb92d9afe74021John Reck mLut = createLUT(interpolator, duration); 45315c329544d7c593d1072b071cbb92d9afe74021John Reck } 46315c329544d7c593d1072b071cbb92d9afe74021John Reck 47ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette private static float[] createLUT(TimeInterpolator interpolator, long duration) { 48315c329544d7c593d1072b071cbb92d9afe74021John Reck long frameIntervalNanos = Choreographer.getInstance().getFrameIntervalNanos(); 49315c329544d7c593d1072b071cbb92d9afe74021John Reck int animIntervalMs = (int) (frameIntervalNanos / TimeUtils.NANOS_PER_MS); 50a5dcc6c25d38fe63a15f1b5920c439696726d3daTeng-Hui Zhu // We need 2 frame values as the minimal. 51a5dcc6c25d38fe63a15f1b5920c439696726d3daTeng-Hui Zhu int numAnimFrames = Math.max(2, (int) Math.ceil(((double) duration) / animIntervalMs)); 52a6b967cfc54408f6ee78ae0e4695eca6efd62e89Doris Liu numAnimFrames = Math.min(numAnimFrames, MAX_SAMPLE_POINTS); 53315c329544d7c593d1072b071cbb92d9afe74021John Reck float values[] = new float[numAnimFrames]; 54315c329544d7c593d1072b071cbb92d9afe74021John Reck float lastFrame = numAnimFrames - 1; 55315c329544d7c593d1072b071cbb92d9afe74021John Reck for (int i = 0; i < numAnimFrames; i++) { 56315c329544d7c593d1072b071cbb92d9afe74021John Reck float inValue = i / lastFrame; 57315c329544d7c593d1072b071cbb92d9afe74021John Reck values[i] = interpolator.getInterpolation(inValue); 58315c329544d7c593d1072b071cbb92d9afe74021John Reck } 59315c329544d7c593d1072b071cbb92d9afe74021John Reck return values; 60315c329544d7c593d1072b071cbb92d9afe74021John Reck } 61315c329544d7c593d1072b071cbb92d9afe74021John Reck 62315c329544d7c593d1072b071cbb92d9afe74021John Reck @Override 63315c329544d7c593d1072b071cbb92d9afe74021John Reck public long createNativeInterpolator() { 64315c329544d7c593d1072b071cbb92d9afe74021John Reck return NativeInterpolatorFactoryHelper.createLutInterpolator(mLut); 65315c329544d7c593d1072b071cbb92d9afe74021John Reck } 66315c329544d7c593d1072b071cbb92d9afe74021John Reck 67315c329544d7c593d1072b071cbb92d9afe74021John Reck /** 68315c329544d7c593d1072b071cbb92d9afe74021John Reck * Used to create a one-shot float[] LUT & native interpolator 69315c329544d7c593d1072b071cbb92d9afe74021John Reck */ 70ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette public static long createNativeInterpolator(TimeInterpolator interpolator, long duration) { 71315c329544d7c593d1072b071cbb92d9afe74021John Reck float[] lut = createLUT(interpolator, duration); 72315c329544d7c593d1072b071cbb92d9afe74021John Reck return NativeInterpolatorFactoryHelper.createLutInterpolator(lut); 73315c329544d7c593d1072b071cbb92d9afe74021John Reck } 74918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck 75918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck @Override 76918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck public float getInterpolation(float input) { 77918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck return mSourceInterpolator.getInterpolation(input); 78918988c1ce5af002d41c7ac37f3fa490558b0c90John Reck } 79315c329544d7c593d1072b071cbb92d9afe74021John Reck} 80