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