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 #ifndef ANIMATOR_H 17 #define ANIMATOR_H 18 19 #include <cutils/compiler.h> 20 #include <utils/RefBase.h> 21 #include <utils/StrongPointer.h> 22 #include <utils/Timers.h> 23 #include <memory> 24 25 #include "utils/Macros.h" 26 27 #include <vector> 28 29 namespace android { 30 namespace uirenderer { 31 32 class AnimationContext; 33 class BaseRenderNodeAnimator; 34 class CanvasPropertyPrimitive; 35 class CanvasPropertyPaint; 36 class Interpolator; 37 class RenderNode; 38 class RenderProperties; 39 40 class AnimationListener : public VirtualLightRefBase { 41 public: 42 ANDROID_API virtual void onAnimationFinished(BaseRenderNodeAnimator*) = 0; 43 44 protected: ~AnimationListener()45 ANDROID_API virtual ~AnimationListener() {} 46 }; 47 48 enum class RepeatMode { 49 // These are the same values as the RESTART and REVERSE in ValueAnimator.java. 50 Restart = 1, 51 Reverse = 2 52 }; 53 54 class BaseRenderNodeAnimator : public VirtualLightRefBase { 55 PREVENT_COPY_AND_ASSIGN(BaseRenderNodeAnimator); 56 57 public: 58 ANDROID_API void setStartValue(float value); 59 ANDROID_API void setInterpolator(Interpolator* interpolator); 60 ANDROID_API void setDuration(nsecs_t durationInMs); duration()61 ANDROID_API nsecs_t duration() { return mDuration; } 62 ANDROID_API void setStartDelay(nsecs_t startDelayInMs); startDelay()63 ANDROID_API nsecs_t startDelay() { return mStartDelay; } setListener(AnimationListener * listener)64 ANDROID_API void setListener(AnimationListener* listener) { mListener = listener; } listener()65 AnimationListener* listener() { return mListener.get(); } setAllowRunningAsync(bool mayRunAsync)66 ANDROID_API void setAllowRunningAsync(bool mayRunAsync) { mMayRunAsync = mayRunAsync; } mayRunAsync()67 bool mayRunAsync() { return mMayRunAsync; } 68 ANDROID_API void start(); 69 ANDROID_API virtual void reset(); 70 ANDROID_API void reverse(); 71 // Terminates the animation at its current progress. 72 ANDROID_API void cancel(); 73 74 // Terminates the animation and skip to the end of the animation. 75 ANDROID_API virtual void end(); 76 77 void attach(RenderNode* target); onAttached()78 virtual void onAttached() {} detach()79 void detach() { mTarget = nullptr; } 80 ANDROID_API void pushStaging(AnimationContext& context); 81 ANDROID_API bool animate(AnimationContext& context); 82 83 // Returns the remaining time in ms for the animation. Note this should only be called during 84 // an animation on RenderThread. 85 ANDROID_API nsecs_t getRemainingPlayTime(); 86 isRunning()87 bool isRunning() { 88 return mPlayState == PlayState::Running || mPlayState == PlayState::Reversing; 89 } isFinished()90 bool isFinished() { return mPlayState == PlayState::Finished; } finalValue()91 float finalValue() { return mFinalValue; } 92 93 ANDROID_API virtual uint32_t dirtyMask() = 0; 94 95 void forceEndNow(AnimationContext& context); target()96 RenderNode* target() { return mTarget; } stagingTarget()97 RenderNode* stagingTarget() { return mStagingTarget; } 98 99 protected: 100 // PlayState is used by mStagingPlayState and mPlayState to track the state initiated from UI 101 // thread and Render Thread animation state, respectively. 102 // From the UI thread, mStagingPlayState transition looks like 103 // NotStarted -> Running/Reversing -> Finished 104 // ^ | 105 // | | 106 // ---------------------- 107 // Note: For mStagingState, the Finished state (optional) is only set when the animation is 108 // terminated by user. 109 // 110 // On Render Thread, mPlayState transition: 111 // NotStart -> Running/Reversing-> Finished 112 // ^ | 113 // | | 114 // ------------------ 115 // Note that if the animation is in Running/Reversing state, calling start or reverse again 116 // would do nothing if the animation has the same play direction as the request; otherwise, 117 // the animation would start from where it is and change direction (i.e. Reversing <-> Running) 118 119 enum class PlayState { 120 NotStarted, 121 Running, 122 Reversing, 123 Finished, 124 }; 125 126 explicit BaseRenderNodeAnimator(float finalValue); 127 virtual ~BaseRenderNodeAnimator(); 128 129 virtual float getValue(RenderNode* target) const = 0; 130 virtual void setValue(RenderNode* target, float value) = 0; 131 132 void callOnFinishedListener(AnimationContext& context); 133 onStagingPlayStateChanged()134 virtual void onStagingPlayStateChanged() {} onPlayTimeChanged(nsecs_t playTime)135 virtual void onPlayTimeChanged(nsecs_t playTime) {} onPushStaging()136 virtual void onPushStaging() {} 137 138 RenderNode* mTarget; 139 RenderNode* mStagingTarget; 140 141 float mFinalValue; 142 float mDeltaValue; 143 float mFromValue; 144 145 std::unique_ptr<Interpolator> mInterpolator; 146 PlayState mStagingPlayState; 147 PlayState mPlayState; 148 bool mHasStartValue; 149 nsecs_t mStartTime; 150 nsecs_t mDuration; 151 nsecs_t mStartDelay; 152 bool mMayRunAsync; 153 // Play Time tracks the progress of animation, it should always be [0, mDuration], 0 being 154 // the beginning of the animation, will reach mDuration at the end of an animation. 155 nsecs_t mPlayTime; 156 157 sp<AnimationListener> mListener; 158 159 private: 160 enum class Request { Start, Reverse, Reset, Cancel, End }; 161 162 // Defines different actions upon finish. 163 enum class Action { 164 // For animations that got canceled or finished normally. no more action needs to be done. 165 None, 166 // For animations that get reset, the reset will happen in the next animation pulse. 167 Reset, 168 // For animations being ended, in the next animation pulse the animation will skip to end. 169 End 170 }; 171 172 inline void checkMutable(); 173 virtual void transitionToRunning(AnimationContext& context); 174 void doSetStartValue(float value); 175 bool updatePlayTime(nsecs_t playTime); 176 void resolveStagingRequest(Request request); 177 178 std::vector<Request> mStagingRequests; 179 Action mPendingActionUponFinish = Action::None; 180 }; 181 182 class RenderPropertyAnimator : public BaseRenderNodeAnimator { 183 public: 184 enum RenderProperty { 185 TRANSLATION_X = 0, 186 TRANSLATION_Y, 187 TRANSLATION_Z, 188 SCALE_X, 189 SCALE_Y, 190 ROTATION, 191 ROTATION_X, 192 ROTATION_Y, 193 X, 194 Y, 195 Z, 196 ALPHA, 197 }; 198 199 ANDROID_API RenderPropertyAnimator(RenderProperty property, float finalValue); 200 201 ANDROID_API virtual uint32_t dirtyMask(); 202 203 protected: 204 virtual float getValue(RenderNode* target) const override; 205 virtual void setValue(RenderNode* target, float value) override; 206 virtual void onAttached() override; 207 virtual void onStagingPlayStateChanged() override; 208 virtual void onPushStaging() override; 209 210 private: 211 typedef bool (RenderProperties::*SetFloatProperty)(float value); 212 typedef float (RenderProperties::*GetFloatProperty)() const; 213 214 struct PropertyAccessors; 215 const PropertyAccessors* mPropertyAccess; 216 217 static const PropertyAccessors PROPERTY_ACCESSOR_LUT[]; 218 bool mShouldSyncPropertyFields = false; 219 bool mShouldUpdateStagingProperties = false; 220 }; 221 222 class CanvasPropertyPrimitiveAnimator : public BaseRenderNodeAnimator { 223 public: 224 ANDROID_API CanvasPropertyPrimitiveAnimator(CanvasPropertyPrimitive* property, 225 float finalValue); 226 227 ANDROID_API virtual uint32_t dirtyMask(); 228 229 protected: 230 virtual float getValue(RenderNode* target) const override; 231 virtual void setValue(RenderNode* target, float value) override; 232 233 private: 234 sp<CanvasPropertyPrimitive> mProperty; 235 }; 236 237 class CanvasPropertyPaintAnimator : public BaseRenderNodeAnimator { 238 public: 239 enum PaintField { 240 STROKE_WIDTH = 0, 241 ALPHA, 242 }; 243 244 ANDROID_API CanvasPropertyPaintAnimator(CanvasPropertyPaint* property, PaintField field, 245 float finalValue); 246 247 ANDROID_API virtual uint32_t dirtyMask(); 248 249 protected: 250 virtual float getValue(RenderNode* target) const override; 251 virtual void setValue(RenderNode* target, float value) override; 252 253 private: 254 sp<CanvasPropertyPaint> mProperty; 255 PaintField mField; 256 }; 257 258 class RevealAnimator : public BaseRenderNodeAnimator { 259 public: 260 ANDROID_API RevealAnimator(int centerX, int centerY, float startValue, float finalValue); 261 262 ANDROID_API virtual uint32_t dirtyMask(); 263 264 protected: 265 virtual float getValue(RenderNode* target) const override; 266 virtual void setValue(RenderNode* target, float value) override; 267 268 private: 269 int mCenterX, mCenterY; 270 }; 271 272 } /* namespace uirenderer */ 273 } /* namespace android */ 274 275 #endif /* ANIMATOR_H */ 276