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