• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "animation/rs_render_animation.h"
17 
18 #include "command/rs_animation_command.h"
19 #include "pipeline/rs_canvas_render_node.h"
20 #include "command/rs_message_processor.h"
21 #include "platform/common/rs_log.h"
22 
23 namespace OHOS {
24 namespace Rosen {
RSRenderAnimation(AnimationId id)25 RSRenderAnimation::RSRenderAnimation(AnimationId id) : id_(id) {}
Marshalling(Parcel & parcel) const26 bool RSRenderAnimation::Marshalling(Parcel& parcel) const
27 {
28     // animationId, targetId
29     if (!(parcel.WriteUint64(id_))) {
30         ROSEN_LOGE("RSRenderAnimation::Marshalling, write id failed");
31         return false;
32     }
33     // RSAnimationTimingProtocol
34     if (!(parcel.WriteInt32(animationFraction_.GetDuration()) &&
35         parcel.WriteInt32(animationFraction_.GetStartDelay()) &&
36         parcel.WriteFloat(animationFraction_.GetSpeed()) &&
37         parcel.WriteInt32(animationFraction_.GetRepeatCount()) &&
38         parcel.WriteBool(animationFraction_.GetAutoReverse()) &&
39         parcel.WriteBool(animationFraction_.GetDirection()) &&
40         parcel.WriteInt32(static_cast<std::underlying_type<FillMode>::type>(animationFraction_.GetFillMode())) &&
41         parcel.WriteBool(animationFraction_.GetRepeatCallbackEnable()) &&
42         parcel.WriteInt32(animationFraction_.GetFrameRateRange().min_) &&
43         parcel.WriteInt32(animationFraction_.GetFrameRateRange().max_) &&
44         parcel.WriteInt32(animationFraction_.GetFrameRateRange().preferred_))) {
45         ROSEN_LOGE("RSRenderAnimation::Marshalling, write param failed");
46         return false;
47     }
48     return true;
49 }
50 
ParseParam(Parcel & parcel)51 bool RSRenderAnimation::ParseParam(Parcel& parcel)
52 {
53     int32_t duration = 0;
54     int32_t startDelay = 0;
55     int32_t repeatCount = 0;
56     int32_t fillMode = 0;
57     float speed = 0.0;
58     bool autoReverse = false;
59     bool direction = false;
60     bool isRepeatCallbackEnable = false;
61     int fpsMin = 0;
62     int fpsMax = 0;
63     int fpsPreferred = 0;
64     if (!(parcel.ReadUint64(id_) && parcel.ReadInt32(duration) && parcel.ReadInt32(startDelay) &&
65             parcel.ReadFloat(speed) && parcel.ReadInt32(repeatCount) && parcel.ReadBool(autoReverse) &&
66             parcel.ReadBool(direction) && parcel.ReadInt32(fillMode) && parcel.ReadBool(isRepeatCallbackEnable) &&
67             parcel.ReadInt32(fpsMin) && parcel.ReadInt32(fpsMax) && parcel.ReadInt32(fpsPreferred))) {
68         ROSEN_LOGE("RSRenderAnimation::ParseParam, read param failed");
69         return false;
70     }
71     SetDuration(duration);
72     SetStartDelay(startDelay);
73     SetRepeatCount(repeatCount);
74     SetAutoReverse(autoReverse);
75     SetSpeed(speed);
76     SetDirection(direction);
77     SetFillMode(static_cast<FillMode>(fillMode));
78     SetRepeatCallbackEnable(isRepeatCallbackEnable);
79     SetFrameRateRange({fpsMin, fpsMax, fpsPreferred});
80     return true;
81 }
GetAnimationId() const82 AnimationId RSRenderAnimation::GetAnimationId() const
83 {
84     return id_;
85 }
86 
IsStarted() const87 bool RSRenderAnimation::IsStarted() const
88 {
89     return state_ != AnimationState::INITIALIZED;
90 }
91 
IsRunning() const92 bool RSRenderAnimation::IsRunning() const
93 {
94     return state_ == AnimationState::RUNNING;
95 }
96 
IsPaused() const97 bool RSRenderAnimation::IsPaused() const
98 {
99     return state_ == AnimationState::PAUSED;
100 }
101 
IsFinished() const102 bool RSRenderAnimation::IsFinished() const
103 {
104     return state_ == AnimationState::FINISHED;
105 }
106 
GetPropertyId() const107 PropertyId RSRenderAnimation::GetPropertyId() const
108 {
109     return 0;
110 }
111 
Attach(RSRenderNode * renderNode)112 void RSRenderAnimation::Attach(RSRenderNode* renderNode)
113 {
114     if (target_ != nullptr) {
115         Detach();
116     }
117     target_ = renderNode;
118     if (target_ != nullptr) {
119         targetId_ = target_->GetId();
120         target_->CheckGroupableAnimation(GetPropertyId(), true);
121     }
122     OnAttach();
123     Start();
124     needUpdateStartTime_ = false;
125 }
126 
Detach()127 void RSRenderAnimation::Detach()
128 {
129     OnDetach();
130     if (target_ != nullptr) {
131         target_->CheckGroupableAnimation(GetPropertyId(), false);
132     }
133     target_ = nullptr;
134 }
135 
GetTargetId() const136 NodeId RSRenderAnimation::GetTargetId() const
137 {
138     return targetId_;
139 }
140 
Start()141 void RSRenderAnimation::Start()
142 {
143     if (IsStarted()) {
144         ROSEN_LOGE("Failed to start animation, animation has started!");
145         return;
146     }
147 
148     state_ = AnimationState::RUNNING;
149     needUpdateStartTime_ = true;
150     ProcessFillModeOnStart(animationFraction_.GetStartFraction());
151 }
152 
Finish()153 void RSRenderAnimation::Finish()
154 {
155     if (!IsPaused() && !IsRunning()) {
156         ROSEN_LOGE("Failed to finish animation, animation is not running!");
157         return;
158     }
159 
160     state_ = AnimationState::FINISHED;
161     ProcessFillModeOnFinish(animationFraction_.GetEndFraction());
162 }
163 
FinishOnCurrentPosition()164 void RSRenderAnimation::FinishOnCurrentPosition()
165 {
166     if (!IsPaused() && !IsRunning()) {
167         ROSEN_LOGE("Failed to finish animation, animation is not running!");
168         return;
169     }
170 
171     state_ = AnimationState::FINISHED;
172 }
173 
Pause()174 void RSRenderAnimation::Pause()
175 {
176     if (!IsRunning()) {
177         ROSEN_LOGE("Failed to pause animation, animation is not running!");
178         return;
179     }
180 
181     state_ = AnimationState::PAUSED;
182 }
183 
Resume()184 void RSRenderAnimation::Resume()
185 {
186     if (!IsPaused()) {
187         ROSEN_LOGE("Failed to resume animation, animation is not paused!");
188         return;
189     }
190 
191     state_ = AnimationState::RUNNING;
192     needUpdateStartTime_ = true;
193 }
194 
SetFraction(float fraction)195 void RSRenderAnimation::SetFraction(float fraction)
196 {
197     if (!IsPaused()) {
198         ROSEN_LOGE("Failed to set fraction, animation is not paused!");
199         return;
200     }
201 
202     fraction = std::min(std::max(fraction, 0.0f), 1.0f);
203     OnSetFraction(fraction);
204 }
205 
SetReversed(bool isReversed)206 void RSRenderAnimation::SetReversed(bool isReversed)
207 {
208     if (!IsPaused() && !IsRunning()) {
209         ROSEN_LOGE("Failed to reverse animation, animation is not running!");
210         return;
211     }
212 
213     animationFraction_.SetDirectionAfterStart(isReversed ? ForwardDirection::REVERSE : ForwardDirection::NORMAL);
214 }
215 
GetTarget() const216 RSRenderNode* RSRenderAnimation::GetTarget() const
217 {
218     return target_;
219 }
220 
SetFractionInner(float fraction)221 void RSRenderAnimation::SetFractionInner(float fraction)
222 {
223     animationFraction_.UpdateRemainTimeFraction(fraction);
224 }
225 
OnSetFraction(float fraction)226 void RSRenderAnimation::OnSetFraction(float fraction)
227 {
228     SetFractionInner(fraction);
229 }
230 
ProcessFillModeOnStart(float startFraction)231 void RSRenderAnimation::ProcessFillModeOnStart(float startFraction)
232 {
233     auto fillMode = GetFillMode();
234     if (fillMode == FillMode::BACKWARDS || fillMode == FillMode::BOTH) {
235         OnAnimate(startFraction);
236     }
237 }
238 
ProcessFillModeOnFinish(float endFraction)239 void RSRenderAnimation::ProcessFillModeOnFinish(float endFraction)
240 {
241     auto fillMode = GetFillMode();
242     if (fillMode == FillMode::FORWARDS || fillMode == FillMode::BOTH) {
243         OnAnimate(endFraction);
244     } else {
245         OnRemoveOnCompletion();
246     }
247 }
248 
ProcessOnRepeatFinish()249 void RSRenderAnimation::ProcessOnRepeatFinish()
250 {
251     std::unique_ptr<RSCommand> command =
252         std::make_unique<RSAnimationCallback>(targetId_, id_, REPEAT_FINISHED);
253     RSMessageProcessor::Instance().AddUIMessage(ExtractPid(id_), command);
254 }
255 
Animate(int64_t time)256 bool RSRenderAnimation::Animate(int64_t time)
257 {
258     if (!IsRunning()) {
259         return state_ == AnimationState::FINISHED;
260     }
261 
262     // set start time and return
263     if (needUpdateStartTime_) {
264         SetStartTime(time);
265         return state_ == AnimationState::FINISHED;
266     }
267 
268     // if time not changed since last frame, return
269     if (time == animationFraction_.GetLastFrameTime()) {
270         return state_ == AnimationState::FINISHED;
271     }
272 
273     if (needInitialize_) {
274         // normally this only run once, but in spring animation with blendDuration, it may run multiple times
275         OnInitialize(time);
276     }
277 
278     // convert time to fraction
279     auto [fraction, isInStartDelay, isFinished, isRepeatFinished] = animationFraction_.GetAnimationFraction(time);
280     if (isInStartDelay) {
281         ProcessFillModeOnStart(fraction);
282         ROSEN_LOGD("RSRenderAnimation::Animate, isInStartDelay is true");
283         return false;
284     }
285 
286     OnAnimate(fraction);
287     if (isRepeatFinished) {
288         ProcessOnRepeatFinish();
289     }
290     if (isFinished) {
291         ProcessFillModeOnFinish(fraction);
292         ROSEN_LOGD("RSRenderAnimation::Animate, isFinished is true");
293         return true;
294     }
295     return isFinished;
296 }
297 
SetStartTime(int64_t time)298 void RSRenderAnimation::SetStartTime(int64_t time)
299 {
300     animationFraction_.SetLastFrameTime(time);
301     needUpdateStartTime_ = false;
302 }
303 } // namespace Rosen
304 } // namespace OHOS
305