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
DumpAnimation(std::string & out) const51 void RSRenderAnimation::DumpAnimation(std::string& out) const
52 {
53 out += "Animation: [id:" + std::to_string(id_) + ", ";
54 DumpAnimationType(out);
55 out += ", AnimationState:" + std::to_string(static_cast<int>(state_));
56 out += ", StartDelay:" + std::to_string(animationFraction_.GetDuration());
57 out += ", Duration:" + std::to_string(animationFraction_.GetStartDelay());
58 out += ", Speed:" + std::to_string(animationFraction_.GetSpeed());
59 out += ", RepeatCount:" + std::to_string(animationFraction_.GetRepeatCount());
60 out += ", AutoReverse:" + std::to_string(animationFraction_.GetAutoReverse());
61 out += ", Direction:" + std::to_string(animationFraction_.GetDirection());
62 out += ", FillMode:" + std::to_string(static_cast<int>(animationFraction_.GetFillMode()));
63 out += ", RepeatCallbackEnable:" + std::to_string(animationFraction_.GetRepeatCallbackEnable());
64 out += ", FrameRateRange_min:" + std::to_string(animationFraction_.GetFrameRateRange().min_);
65 out += ", FrameRateRange_max:" + std::to_string(animationFraction_.GetFrameRateRange().max_);
66 out += ", FrameRateRange_prefered:" + std::to_string(animationFraction_.GetFrameRateRange().preferred_);
67 out += "]";
68 }
69
DumpAnimationType(std::string & out) const70 void RSRenderAnimation::DumpAnimationType(std::string& out) const
71 {
72 out += "Type:Unknown";
73 }
74
ParseParam(Parcel & parcel)75 bool RSRenderAnimation::ParseParam(Parcel& parcel)
76 {
77 int32_t duration = 0;
78 int32_t startDelay = 0;
79 int32_t repeatCount = 0;
80 int32_t fillMode = 0;
81 float speed = 0.0;
82 bool autoReverse = false;
83 bool direction = false;
84 bool isRepeatCallbackEnable = false;
85 int fpsMin = 0;
86 int fpsMax = 0;
87 int fpsPreferred = 0;
88 if (!(parcel.ReadUint64(id_) && parcel.ReadInt32(duration) && parcel.ReadInt32(startDelay) &&
89 parcel.ReadFloat(speed) && parcel.ReadInt32(repeatCount) && parcel.ReadBool(autoReverse) &&
90 parcel.ReadBool(direction) && parcel.ReadInt32(fillMode) && parcel.ReadBool(isRepeatCallbackEnable) &&
91 parcel.ReadInt32(fpsMin) && parcel.ReadInt32(fpsMax) && parcel.ReadInt32(fpsPreferred))) {
92 ROSEN_LOGE("RSRenderAnimation::ParseParam, read param failed");
93 return false;
94 }
95 SetDuration(duration);
96 SetStartDelay(startDelay);
97 SetRepeatCount(repeatCount);
98 SetAutoReverse(autoReverse);
99 SetSpeed(speed);
100 SetDirection(direction);
101 SetFillMode(static_cast<FillMode>(fillMode));
102 SetRepeatCallbackEnable(isRepeatCallbackEnable);
103 SetFrameRateRange({fpsMin, fpsMax, fpsPreferred});
104 return true;
105 }
GetAnimationId() const106 AnimationId RSRenderAnimation::GetAnimationId() const
107 {
108 return id_;
109 }
110
IsStarted() const111 bool RSRenderAnimation::IsStarted() const
112 {
113 return state_ != AnimationState::INITIALIZED;
114 }
115
IsRunning() const116 bool RSRenderAnimation::IsRunning() const
117 {
118 return state_ == AnimationState::RUNNING;
119 }
120
IsPaused() const121 bool RSRenderAnimation::IsPaused() const
122 {
123 return state_ == AnimationState::PAUSED;
124 }
125
IsFinished() const126 bool RSRenderAnimation::IsFinished() const
127 {
128 return state_ == AnimationState::FINISHED;
129 }
130
GetPropertyId() const131 PropertyId RSRenderAnimation::GetPropertyId() const
132 {
133 return 0;
134 }
135
Attach(RSRenderNode * renderNode)136 void RSRenderAnimation::Attach(RSRenderNode* renderNode)
137 {
138 if (target_ != nullptr) {
139 Detach();
140 }
141 target_ = renderNode;
142 if (target_ != nullptr) {
143 targetId_ = target_->GetId();
144 target_->CheckGroupableAnimation(GetPropertyId(), true);
145 }
146 OnAttach();
147 Start();
148 needUpdateStartTime_ = false;
149 }
150
Detach(bool forceDetach)151 void RSRenderAnimation::Detach(bool forceDetach)
152 {
153 if (!forceDetach) {
154 OnDetach();
155 if (target_ != nullptr) {
156 target_->CheckGroupableAnimation(GetPropertyId(), false);
157 }
158 }
159 target_ = nullptr;
160 }
161
GetTargetId() const162 NodeId RSRenderAnimation::GetTargetId() const
163 {
164 return targetId_;
165 }
166
Start()167 void RSRenderAnimation::Start()
168 {
169 if (IsStarted()) {
170 ROSEN_LOGE("Failed to start animation, animation has started!");
171 return;
172 }
173
174 state_ = AnimationState::RUNNING;
175 needUpdateStartTime_ = true;
176 ProcessFillModeOnStart(animationFraction_.GetStartFraction());
177 }
178
Finish()179 void RSRenderAnimation::Finish()
180 {
181 if (!IsPaused() && !IsRunning()) {
182 ROSEN_LOGD("Failed to finish animation, animation is not running!");
183 return;
184 }
185
186 state_ = AnimationState::FINISHED;
187 ProcessFillModeOnFinish(animationFraction_.GetEndFraction());
188 }
189
FinishOnCurrentPosition()190 void RSRenderAnimation::FinishOnCurrentPosition()
191 {
192 if (!IsPaused() && !IsRunning()) {
193 ROSEN_LOGD("Failed to finish animation, animation is not running!");
194 return;
195 }
196
197 state_ = AnimationState::FINISHED;
198 }
199
Pause()200 void RSRenderAnimation::Pause()
201 {
202 if (!IsRunning()) {
203 ROSEN_LOGE("Failed to pause animation, animation is not running!");
204 return;
205 }
206
207 state_ = AnimationState::PAUSED;
208 }
209
Resume()210 void RSRenderAnimation::Resume()
211 {
212 if (!IsPaused()) {
213 ROSEN_LOGE("Failed to resume animation, animation is not paused!");
214 return;
215 }
216
217 state_ = AnimationState::RUNNING;
218 needUpdateStartTime_ = true;
219 }
220
SetFraction(float fraction)221 void RSRenderAnimation::SetFraction(float fraction)
222 {
223 if (!IsPaused()) {
224 ROSEN_LOGE("Failed to set fraction, animation is not paused!");
225 return;
226 }
227
228 fraction = std::min(std::max(fraction, 0.0f), 1.0f);
229 OnSetFraction(fraction);
230 }
231
SetReversed(bool isReversed)232 void RSRenderAnimation::SetReversed(bool isReversed)
233 {
234 if (!IsPaused() && !IsRunning()) {
235 ROSEN_LOGE("Failed to reverse animation, animation is not running!");
236 return;
237 }
238
239 animationFraction_.SetDirectionAfterStart(isReversed ? ForwardDirection::REVERSE : ForwardDirection::NORMAL);
240 }
241
GetTarget() const242 RSRenderNode* RSRenderAnimation::GetTarget() const
243 {
244 return target_;
245 }
246
SetFractionInner(float fraction)247 void RSRenderAnimation::SetFractionInner(float fraction)
248 {
249 animationFraction_.UpdateRemainTimeFraction(fraction);
250 }
251
OnSetFraction(float fraction)252 void RSRenderAnimation::OnSetFraction(float fraction)
253 {
254 SetFractionInner(fraction);
255 }
256
ProcessFillModeOnStart(float startFraction)257 void RSRenderAnimation::ProcessFillModeOnStart(float startFraction)
258 {
259 auto fillMode = GetFillMode();
260 if (fillMode == FillMode::BACKWARDS || fillMode == FillMode::BOTH) {
261 OnAnimate(startFraction);
262 }
263 }
264
ProcessFillModeOnFinish(float endFraction)265 void RSRenderAnimation::ProcessFillModeOnFinish(float endFraction)
266 {
267 auto fillMode = GetFillMode();
268 if (fillMode == FillMode::FORWARDS || fillMode == FillMode::BOTH) {
269 OnAnimate(endFraction);
270 } else {
271 OnRemoveOnCompletion();
272 }
273 }
274
ProcessOnRepeatFinish()275 void RSRenderAnimation::ProcessOnRepeatFinish()
276 {
277 std::unique_ptr<RSCommand> command =
278 std::make_unique<RSAnimationCallback>(targetId_, id_, REPEAT_FINISHED);
279 RSMessageProcessor::Instance().AddUIMessage(ExtractPid(id_), command);
280 }
281
Animate(int64_t time)282 bool RSRenderAnimation::Animate(int64_t time)
283 {
284 // calculateAnimationValue_ is embedded modify for stat animate frame drop
285 calculateAnimationValue_ = true;
286
287 if (!IsRunning()) {
288 return state_ == AnimationState::FINISHED;
289 }
290
291 // set start time and return
292 if (needUpdateStartTime_) {
293 SetStartTime(time);
294 return state_ == AnimationState::FINISHED;
295 }
296
297 // if time not changed since last frame, return
298 if (time == animationFraction_.GetLastFrameTime()) {
299 return state_ == AnimationState::FINISHED;
300 }
301
302 if (needInitialize_) {
303 // normally this only run once, but in spring animation with blendDuration, it may run multiple times
304 OnInitialize(time);
305 }
306
307 // calculate frame time interval in seconds
308 float frameInterval = (time - animationFraction_.GetLastFrameTime()) * 1.0f / NS_TO_S;
309
310 // convert time to fraction
311 auto [fraction, isInStartDelay, isFinished, isRepeatFinished] = animationFraction_.GetAnimationFraction(time);
312 if (isInStartDelay) {
313 calculateAnimationValue_ = false;
314 ProcessFillModeOnStart(fraction);
315 ROSEN_LOGD("RSRenderAnimation::Animate, isInStartDelay is true");
316 return false;
317 }
318
319 RecordLastAnimateValue();
320 OnAnimate(fraction);
321 UpdateAnimateVelocity(frameInterval);
322
323 if (isRepeatFinished) {
324 ProcessOnRepeatFinish();
325 }
326 if (isFinished) {
327 ProcessFillModeOnFinish(fraction);
328 ROSEN_LOGD("RSRenderAnimation::Animate, isFinished is true");
329 return true;
330 }
331 return isFinished;
332 }
333
SetStartTime(int64_t time)334 void RSRenderAnimation::SetStartTime(int64_t time)
335 {
336 animationFraction_.SetLastFrameTime(time);
337 needUpdateStartTime_ = false;
338 }
339
GetAnimateVelocity() const340 const std::shared_ptr<RSRenderPropertyBase> RSRenderAnimation::GetAnimateVelocity() const
341 {
342 return animateVelocity_;
343 }
344
345 bool RSRenderAnimation::isCalcAnimateVelocity_ = true;
346 } // namespace Rosen
347 } // namespace OHOS
348