Animator.cpp revision ff941dcd815021bb20d6504eb486acb1e50592c3
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 17#define LOG_TAG "RT-Animator" 18 19#include "Animator.h" 20 21#include <set> 22 23#include "RenderNode.h" 24#include "RenderProperties.h" 25 26namespace android { 27namespace uirenderer { 28 29/************************************************************ 30 * BaseRenderNodeAnimator 31 ************************************************************/ 32 33BaseRenderNodeAnimator::BaseRenderNodeAnimator(float finalValue) 34 : mFinalValue(finalValue) 35 , mDeltaValue(0) 36 , mFromValue(0) 37 , mInterpolator(0) 38 , mPlayState(NEEDS_START) 39 , mStartTime(0) 40 , mDuration(300){ 41} 42 43BaseRenderNodeAnimator::~BaseRenderNodeAnimator() { 44 setInterpolator(NULL); 45} 46 47void BaseRenderNodeAnimator::setInterpolator(Interpolator* interpolator) { 48 delete mInterpolator; 49 mInterpolator = interpolator; 50} 51 52void BaseRenderNodeAnimator::setDuration(nsecs_t duration) { 53 mDuration = duration; 54} 55 56void BaseRenderNodeAnimator::setStartValue(float value) { 57 LOG_ALWAYS_FATAL_IF(mPlayState != NEEDS_START, 58 "Cannot set the start value after the animator has started!"); 59 mFromValue = value; 60 mDeltaValue = (mFinalValue - mFromValue); 61 mPlayState = PENDING; 62} 63 64void BaseRenderNodeAnimator::setupStartValueIfNecessary(RenderNode* target, TreeInfo& info) { 65 if (mPlayState == NEEDS_START) { 66 setStartValue(getValue(target)); 67 mPlayState = PENDING; 68 } 69} 70 71bool BaseRenderNodeAnimator::animate(RenderNode* target, TreeInfo& info) { 72 if (mPlayState == PENDING) { 73 mPlayState = RUNNING; 74 mStartTime = info.frameTimeMs; 75 // No interpolator was set, use the default 76 if (!mInterpolator) { 77 setInterpolator(Interpolator::createDefaultInterpolator()); 78 } 79 } 80 81 float fraction = 1.0f; 82 if (mPlayState == RUNNING) { 83 fraction = mDuration > 0 ? (float)(info.frameTimeMs - mStartTime) / mDuration : 1.0f; 84 if (fraction >= 1.0f) { 85 fraction = 1.0f; 86 mPlayState = FINISHED; 87 } 88 } 89 fraction = mInterpolator->interpolate(fraction); 90 setValue(target, mFromValue + (mDeltaValue * fraction)); 91 92 if (mPlayState == FINISHED) { 93 callOnFinishedListener(info); 94 return true; 95 } 96 return false; 97} 98 99void BaseRenderNodeAnimator::callOnFinishedListener(TreeInfo& info) { 100 if (mListener.get()) { 101 if (!info.animationHook) { 102 mListener->onAnimationFinished(this); 103 } else { 104 info.animationHook->callOnFinished(this, mListener.get()); 105 } 106 } 107} 108 109/************************************************************ 110 * RenderPropertyAnimator 111 ************************************************************/ 112 113struct RenderPropertyAnimator::PropertyAccessors { 114 RenderNode::DirtyPropertyMask dirtyMask; 115 GetFloatProperty getter; 116 SetFloatProperty setter; 117}; 118 119// Maps RenderProperty enum to accessors 120const RenderPropertyAnimator::PropertyAccessors RenderPropertyAnimator::PROPERTY_ACCESSOR_LUT[] = { 121 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationX, &RenderProperties::setTranslationX }, 122 {RenderNode::TRANSLATION_Y, &RenderProperties::getTranslationY, &RenderProperties::setTranslationY }, 123 {RenderNode::TRANSLATION_X, &RenderProperties::getTranslationZ, &RenderProperties::setTranslationZ }, 124 {RenderNode::SCALE_X, &RenderProperties::getScaleX, &RenderProperties::setScaleX }, 125 {RenderNode::SCALE_Y, &RenderProperties::getScaleY, &RenderProperties::setScaleY }, 126 {RenderNode::ROTATION, &RenderProperties::getRotation, &RenderProperties::setRotation }, 127 {RenderNode::ROTATION_X, &RenderProperties::getRotationX, &RenderProperties::setRotationX }, 128 {RenderNode::ROTATION_Y, &RenderProperties::getRotationY, &RenderProperties::setRotationY }, 129 {RenderNode::X, &RenderProperties::getX, &RenderProperties::setX }, 130 {RenderNode::Y, &RenderProperties::getY, &RenderProperties::setY }, 131 {RenderNode::Z, &RenderProperties::getZ, &RenderProperties::setZ }, 132 {RenderNode::ALPHA, &RenderProperties::getAlpha, &RenderProperties::setAlpha }, 133}; 134 135RenderPropertyAnimator::RenderPropertyAnimator(RenderProperty property, float finalValue) 136 : BaseRenderNodeAnimator(finalValue) 137 , mPropertyAccess(&(PROPERTY_ACCESSOR_LUT[property])) { 138} 139 140void RenderPropertyAnimator::onAttached(RenderNode* target) { 141 if (target->isPropertyFieldDirty(mPropertyAccess->dirtyMask)) { 142 setStartValue((target->stagingProperties().*mPropertyAccess->getter)()); 143 } 144 (target->mutateStagingProperties().*mPropertyAccess->setter)(finalValue()); 145} 146 147float RenderPropertyAnimator::getValue(RenderNode* target) const { 148 return (target->properties().*mPropertyAccess->getter)(); 149} 150 151void RenderPropertyAnimator::setValue(RenderNode* target, float value) { 152 (target->animatorProperties().*mPropertyAccess->setter)(value); 153} 154 155/************************************************************ 156 * CanvasPropertyPrimitiveAnimator 157 ************************************************************/ 158 159CanvasPropertyPrimitiveAnimator::CanvasPropertyPrimitiveAnimator( 160 CanvasPropertyPrimitive* property, float finalValue) 161 : BaseRenderNodeAnimator(finalValue) 162 , mProperty(property) { 163} 164 165float CanvasPropertyPrimitiveAnimator::getValue(RenderNode* target) const { 166 return mProperty->value; 167} 168 169void CanvasPropertyPrimitiveAnimator::setValue(RenderNode* target, float value) { 170 mProperty->value = value; 171} 172 173/************************************************************ 174 * CanvasPropertySkPaintAnimator 175 ************************************************************/ 176 177CanvasPropertyPaintAnimator::CanvasPropertyPaintAnimator( 178 CanvasPropertyPaint* property, PaintField field, float finalValue) 179 : BaseRenderNodeAnimator(finalValue) 180 , mProperty(property) 181 , mField(field) { 182} 183 184float CanvasPropertyPaintAnimator::getValue(RenderNode* target) const { 185 switch (mField) { 186 case STROKE_WIDTH: 187 return mProperty->value.getStrokeWidth(); 188 case ALPHA: 189 return mProperty->value.getAlpha(); 190 } 191 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField); 192 return -1; 193} 194 195static uint8_t to_uint8(float value) { 196 int c = (int) (value + .5f); 197 return static_cast<uint8_t>( c < 0 ? 0 : c > 255 ? 255 : c ); 198} 199 200void CanvasPropertyPaintAnimator::setValue(RenderNode* target, float value) { 201 switch (mField) { 202 case STROKE_WIDTH: 203 mProperty->value.setStrokeWidth(value); 204 return; 205 case ALPHA: 206 mProperty->value.setAlpha(to_uint8(value)); 207 return; 208 } 209 LOG_ALWAYS_FATAL("Unknown field %d", (int) mField); 210} 211 212} /* namespace uirenderer */ 213} /* namespace android */ 214