• 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 "common/rs_optional_trace.h"
20 #include "pipeline/rs_canvas_render_node.h"
21 #include "command/rs_message_processor.h"
22 #include "platform/common/rs_log.h"
23 #include "rs_profiler.h"
24 
25 namespace OHOS {
26 namespace Rosen {
RSRenderAnimation(AnimationId id)27 RSRenderAnimation::RSRenderAnimation(AnimationId id) : id_(id) {}
28 
DumpAnimation(std::string & out) const29 void RSRenderAnimation::DumpAnimation(std::string& out) const
30 {
31     out.append("Animation: [id:").append(std::to_string(id_)).append(", ");
32     DumpAnimationInfo(out);
33     out.append(", AnimationState:").append(std::to_string(static_cast<int>(state_)));
34     if (!targetName_.empty()) {
35         out.append(", NodeName:").append(targetName_);
36     }
37     out.append(", Duration:").append(std::to_string(animationFraction_.GetDuration()));
38     out.append(", runningTime:").append(std::to_string(animationFraction_.GetRunningTime()));
39     if (animationFraction_.GetStartDelay() != 0) {
40         out.append(", StartDelay:").append(std::to_string(animationFraction_.GetStartDelay()));
41     }
42     if (ROSEN_NE(animationFraction_.GetSpeed(), 1.0f)) {
43         out.append(", Speed:").append(std::to_string(animationFraction_.GetSpeed()));
44     }
45     if (animationFraction_.GetRepeatCount() != 1) {
46         out.append(", RepeatCount:").append(std::to_string(animationFraction_.GetRepeatCount()));
47     }
48     if (animationFraction_.GetAutoReverse()) {
49         out.append(", AutoReverse:").append(std::to_string(animationFraction_.GetAutoReverse()));
50     }
51     if (!animationFraction_.GetDirection()) {
52         out.append(", Direction:").append(std::to_string(animationFraction_.GetDirection()));
53     }
54     if (animationFraction_.GetFillMode() != FillMode::FORWARDS) {
55         out.append(", FillMode:").append(std::to_string(static_cast<int>(animationFraction_.GetFillMode())));
56     }
57     if (animationFraction_.GetRepeatCallbackEnable()) {
58         out.append(", RepeatCallbackEnable:").append(std::to_string(animationFraction_.GetRepeatCallbackEnable()));
59     }
60     out.append(", FrameRateRange_min:").append(std::to_string(animationFraction_.GetFrameRateRange().min_));
61     out.append(", FrameRateRange_max:").append(std::to_string(animationFraction_.GetFrameRateRange().max_));
62     out.append(", FrameRateRange_prefered:").append(std::to_string(animationFraction_.GetFrameRateRange().preferred_));
63     out.append(", FrameRateRange_componentScene:").append(animationFraction_.GetFrameRateRange().GetComponentName());
64     out.append(", Token:").append(std::to_string(token_));
65     out.append("]");
66 }
67 
DumpAnimationInfo(std::string & out) const68 void RSRenderAnimation::DumpAnimationInfo(std::string& out) const
69 {
70     out.append("Type:Unknown");
71 }
72 
GetAnimationId() const73 AnimationId RSRenderAnimation::GetAnimationId() const
74 {
75     return id_;
76 }
77 
IsStarted() const78 bool RSRenderAnimation::IsStarted() const
79 {
80     return state_ != AnimationState::INITIALIZED;
81 }
82 
IsRunning() const83 bool RSRenderAnimation::IsRunning() const
84 {
85     return state_ == AnimationState::RUNNING;
86 }
87 
IsPaused() const88 bool RSRenderAnimation::IsPaused() const
89 {
90     return state_ == AnimationState::PAUSED;
91 }
92 
IsFinished() const93 bool RSRenderAnimation::IsFinished() const
94 {
95     return state_ == AnimationState::FINISHED;
96 }
97 
GetPropertyId() const98 PropertyId RSRenderAnimation::GetPropertyId() const
99 {
100     return 0;
101 }
102 
Attach(RSRenderNode * renderNode)103 void RSRenderAnimation::Attach(RSRenderNode* renderNode)
104 {
105     if (target_ != nullptr) {
106         Detach();
107     }
108     target_ = renderNode;
109     if (target_ != nullptr) {
110         targetId_ = target_->GetId();
111         targetName_ = target_->GetNodeName();
112     }
113     OnAttach();
114     Start();
115     needUpdateStartTime_ = false;
116 }
117 
Detach(bool forceDetach)118 void RSRenderAnimation::Detach(bool forceDetach)
119 {
120     if (!forceDetach) {
121         OnDetach();
122     }
123     target_ = nullptr;
124     targetId_ = 0;
125     targetName_ = "";
126 }
127 
GetTargetId() const128 NodeId RSRenderAnimation::GetTargetId() const
129 {
130     return targetId_;
131 }
132 
GetTargetName() const133 const std::string RSRenderAnimation::GetTargetName() const
134 {
135     return targetName_;
136 }
137 
Start()138 void RSRenderAnimation::Start()
139 {
140     if (IsStarted()) {
141         ROSEN_LOGE("Failed to start animation, animation has started!");
142         return;
143     }
144 
145     state_ = AnimationState::RUNNING;
146     needUpdateStartTime_ = true;
147     ProcessFillModeOnStart(animationFraction_.GetStartFraction());
148 }
149 
Finish()150 void RSRenderAnimation::Finish()
151 {
152     RS_LOGI_LIMIT("Animation[%{public}" PRIu64 "] received finish", id_);
153     if (!IsPaused() && !IsRunning()) {
154         ROSEN_LOGD("Failed to finish animation, animation is not running!");
155         return;
156     }
157 
158     state_ = AnimationState::FINISHED;
159     ProcessFillModeOnFinish(animationFraction_.GetEndFraction());
160 }
161 
FinishOnPosition(RSInteractiveAnimationPosition pos)162 void RSRenderAnimation::FinishOnPosition(RSInteractiveAnimationPosition pos)
163 {
164     if (!IsPaused() && !IsRunning()) {
165         ROSEN_LOGD("Failed to finish animation, animation is not running!");
166         return;
167     }
168 
169     state_ = AnimationState::FINISHED;
170 
171     if (pos == RSInteractiveAnimationPosition::START) {
172         ProcessFillModeOnFinish(animationFraction_.GetStartFraction());
173     } else if (pos == RSInteractiveAnimationPosition::END) {
174         ProcessFillModeOnFinish(animationFraction_.GetEndFraction());
175     }
176 }
177 
FinishOnCurrentPosition()178 void RSRenderAnimation::FinishOnCurrentPosition()
179 {
180     if (!IsPaused() && !IsRunning()) {
181         ROSEN_LOGD("Failed to finish animation, animation is not running!");
182         return;
183     }
184 
185     state_ = AnimationState::FINISHED;
186 }
187 
Pause()188 void RSRenderAnimation::Pause()
189 {
190     RS_LOGI_LIMIT("Animation[%{public}" PRIu64 "] received pause", id_);
191     if (!IsRunning()) {
192         ROSEN_LOGE("Failed to pause animation, animation is not running!");
193         return;
194     }
195 
196     state_ = AnimationState::PAUSED;
197 }
198 
Resume()199 void RSRenderAnimation::Resume()
200 {
201     RS_LOGI_LIMIT("Animation[%{public}" PRIu64 "] received resume", id_);
202     if (!IsPaused()) {
203         ROSEN_LOGE("Failed to resume animation, animation is not paused!");
204         return;
205     }
206 
207     state_ = AnimationState::RUNNING;
208     needUpdateStartTime_ = true;
209 
210     UpdateFractionAfterContinue();
211 }
212 
SetFraction(float fraction)213 void RSRenderAnimation::SetFraction(float fraction)
214 {
215     if (!IsPaused()) {
216         ROSEN_LOGE("Failed to set fraction, animation is not paused!");
217         return;
218     }
219 
220     fraction = std::min(std::max(fraction, 0.0f), 1.0f);
221     OnSetFraction(fraction);
222 }
223 
SetReversedAndContinue()224 void RSRenderAnimation::SetReversedAndContinue()
225 {
226     if (!IsPaused()) {
227         ROSEN_LOGE("Failed to reverse animation, animation is not running!");
228         return;
229     }
230     SetReversed(true);
231     animationFraction_.SetDirectionAfterStart(ForwardDirection::REVERSE);
232     Resume();
233 }
234 
235 
SetReversed(bool isReversed)236 void RSRenderAnimation::SetReversed(bool isReversed)
237 {
238     if (!IsPaused() && !IsRunning()) {
239         ROSEN_LOGE("Failed to reverse animation, animation is not running!");
240         return;
241     }
242 
243     animationFraction_.SetDirectionAfterStart(isReversed ? ForwardDirection::REVERSE : ForwardDirection::NORMAL);
244 }
245 
GetTarget() const246 RSRenderNode* RSRenderAnimation::GetTarget() const
247 {
248     return target_;
249 }
250 
SetFractionInner(float fraction)251 void RSRenderAnimation::SetFractionInner(float fraction)
252 {
253     animationFraction_.UpdateRemainTimeFraction(fraction);
254 }
255 
ProcessFillModeOnStart(float startFraction)256 void RSRenderAnimation::ProcessFillModeOnStart(float startFraction)
257 {
258     auto fillMode = GetFillMode();
259     if (fillMode == FillMode::BACKWARDS || fillMode == FillMode::BOTH) {
260         OnAnimate(startFraction);
261     }
262 }
263 
ProcessFillModeOnFinish(float endFraction)264 void RSRenderAnimation::ProcessFillModeOnFinish(float endFraction)
265 {
266     auto fillMode = GetFillMode();
267     if (fillMode == FillMode::FORWARDS || fillMode == FillMode::BOTH) {
268         OnAnimate(endFraction);
269     } else {
270         OnRemoveOnCompletion();
271     }
272 }
273 
ProcessOnRepeatFinish()274 void RSRenderAnimation::ProcessOnRepeatFinish()
275 {
276     std::unique_ptr<RSCommand> command =
277         std::make_unique<RSAnimationCallback>(targetId_, id_, token_, REPEAT_FINISHED);
278     RSMessageProcessor::Instance().AddUIMessage(ExtractPid(id_), command);
279 }
280 
Animate(int64_t time,int64_t & minLeftDelayTime)281 bool RSRenderAnimation::Animate(int64_t time, int64_t& minLeftDelayTime)
282 {
283     // calculateAnimationValue_ is embedded modify for stat animate frame drop
284     calculateAnimationValue_ = true;
285 
286     if (!IsRunning()) {
287         ROSEN_LOGD("RSRenderAnimation::Animate, IsRunning is false!");
288         RS_OPTIONAL_TRACE_NAME_FMT("Animation[%llu] animate not running, state is [%d]", id_, state_);
289         return state_ == AnimationState::FINISHED;
290     }
291 
292     // set start time and return
293     if (needUpdateStartTime_) {
294         SetStartTime(time);
295         minLeftDelayTime = 0;
296         return state_ == AnimationState::FINISHED;
297     }
298 
299     // if time not changed since last frame, return
300     if (time == animationFraction_.GetLastFrameTime()) {
301         minLeftDelayTime = 0;
302         return state_ == AnimationState::FINISHED;
303     }
304 
305     if (needInitialize_) {
306         // normally this only run once, but in spring animation with blendDuration, it may run multiple times
307         OnInitialize(time);
308     }
309 
310     // calculate frame time interval in seconds
311     float frameInterval = (time - animationFraction_.GetLastFrameTime()) * 1.0f / NS_TO_S;
312 
313     // convert time to fraction
314     auto [fraction, isInStartDelay, isFinished, isRepeatFinished] =
315         animationFraction_.GetAnimationFraction(time, minLeftDelayTime);
316     if (isInStartDelay) {
317         calculateAnimationValue_ = false;
318         ProcessFillModeOnStart(fraction);
319         ROSEN_LOGD("RSRenderAnimation::Animate, isInStartDelay is true");
320         return false;
321     }
322 
323     RecordLastAnimateValue();
324     OnAnimate(fraction);
325     DumpFraction(fraction, time);
326     UpdateAnimateVelocity(frameInterval);
327 
328     if (isRepeatFinished) {
329         ProcessOnRepeatFinish();
330     }
331     if (isFinished) {
332         RS_PROFILER_ANIMATION_DURATION_STOP(id_, time);
333         ProcessFillModeOnFinish(fraction);
334         ROSEN_LOGD("RSRenderAnimation::Animate, isFinished is true");
335         return true;
336     }
337     return isFinished;
338 }
339 
SetStartTime(int64_t time)340 void RSRenderAnimation::SetStartTime(int64_t time)
341 {
342     RS_PROFILER_ANIMATION_DURATION_START(id_, time);
343 
344     time = RS_PROFILER_ANIME_SET_START_TIME(id_, time);
345     animationFraction_.SetLastFrameTime(time);
346     needUpdateStartTime_ = false;
347 }
348 
GetAnimateVelocity() const349 const std::shared_ptr<RSRenderPropertyBase>& RSRenderAnimation::GetAnimateVelocity() const
350 {
351     return animateVelocity_;
352 }
353 
354 bool RSRenderAnimation::isCalcAnimateVelocity_ = true;
355 } // namespace Rosen
356 } // namespace OHOS
357