• 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_animation_manager.h"
17 
18 #include <algorithm>
19 #include <string>
20 
21 #include "animation/rs_animation_trace_utils.h"
22 #include "animation/rs_render_animation.h"
23 #include "command/rs_animation_command.h"
24 #include "command/rs_message_processor.h"
25 #include "common/rs_optional_trace.h"
26 #include "pipeline/rs_dirty_region_manager.h"
27 #include "pipeline/rs_paint_filter_canvas.h"
28 #include "pipeline/rs_render_node.h"
29 #include "platform/common/rs_log.h"
30 #include "rs_trace.h"
31 
32 namespace OHOS {
33 namespace Rosen {
34 class RSRootRenderNode;
35 
DumpAnimations(std::string & out) const36 void RSAnimationManager::DumpAnimations(std::string& out) const
37 {
38     RS_TRACE_NAME_FMT("DumpAnimations, size: %zu", animations_.size());
39     if (animations_.empty()) {
40         return;
41     }
42     const auto lengthTwo = 2;
43     out.append(", RSAnimationManager: [");
44     for (auto[id, animation]: animations_) {
45         animation->DumpAnimation(out);
46         out.append(", ");
47     }
48     out.erase(out.end() - lengthTwo, out.end());
49     out.append("]");
50 }
51 
AddAnimation(const std::shared_ptr<RSRenderAnimation> & animation)52 void RSAnimationManager::AddAnimation(const std::shared_ptr<RSRenderAnimation>& animation)
53 {
54     if (animation == nullptr) {
55         ROSEN_LOGE("RSAnimationManager::AddAnimation, The animation is nullptr");
56         return;
57     }
58     AnimationId key = animation->GetAnimationId();
59     if (animations_.find(key) != animations_.end()) {
60         ROSEN_LOGE("RSAnimationManager::AddAnimation, The animation already exists when is added");
61         return;
62     }
63     auto it = std::find(pendingCancelAnimation_.begin(), pendingCancelAnimation_.end(), key);
64     if (it != pendingCancelAnimation_.end()) {
65         pendingCancelAnimation_.erase(it);
66         ROSEN_LOGE("RSAnimationManager::AddAnimation, animation is a pendingCancelAnimation");
67         return;
68     }
69     animations_.emplace(key, animation);
70 }
71 
RemoveAnimation(AnimationId keyId)72 void RSAnimationManager::RemoveAnimation(AnimationId keyId)
73 {
74     auto animationItr = animations_.find(keyId);
75     if (animationItr == animations_.end()) {
76         ROSEN_LOGE("RSAnimationManager::RemoveAnimation, The Animation does not exist when is deleted");
77         return;
78     }
79     animationItr->second->Finish();
80     animationItr->second->Detach();
81     animations_.erase(animationItr);
82 }
83 
CancelAnimationByPropertyId(PropertyId id)84 void RSAnimationManager::CancelAnimationByPropertyId(PropertyId id)
85 {
86     EraseIf(animations_, [id, this](const auto& pair) {
87         if (pair.second && (pair.second->GetPropertyId() == id)) {
88             OnAnimationFinished(pair.second);
89             return true;
90         }
91         return false;
92     });
93 }
94 
AttemptCancelAnimationByAnimationId(const std::vector<AnimationId> & animations)95 void RSAnimationManager::AttemptCancelAnimationByAnimationId(const std::vector<AnimationId>& animations)
96 {
97     for (auto& animationId : animations) {
98         bool isErased = EraseIf(animations_, [animationId, this](const auto& pair) {
99             if (pair.second && (pair.first == animationId)) {
100                 OnAnimationFinished(pair.second);
101                 return true;
102             }
103             return false;
104         });
105         if (!isErased) {
106             pendingCancelAnimation_.emplace_back(animationId);
107         }
108     }
109 }
110 
FilterAnimationByPid(pid_t pid)111 void RSAnimationManager::FilterAnimationByPid(pid_t pid)
112 {
113     ROSEN_LOGD("RSAnimationManager::FilterAnimationByPid removing all animations belong to pid %{public}llu",
114         (unsigned long long)pid);
115     // remove all animations belong to given pid (by matching higher 32 bits of animation id)
116     EraseIf(animations_, [pid, this](const auto& pair) -> bool {
117         if (ExtractPid(pair.first) != pid) {
118             return false;
119         }
120         if (!pair.second) {
121             return false;
122         }
123         pair.second->Finish();
124         pair.second->Detach();
125         return true;
126     });
127 }
128 
GetAnimationsSize()129 uint32_t RSAnimationManager::GetAnimationsSize()
130 {
131     return animations_.size();
132 }
133 
GetAnimationPid() const134 pid_t RSAnimationManager::GetAnimationPid() const
135 {
136     if (animations_.size() > 0) {
137         // shift right 32-bit numbers to get pid
138         return animations_.begin()->first >> 32;
139     }
140     return 0;
141 }
142 
Animate(int64_t time,int64_t & minLeftDelayTime,bool nodeIsOnTheTree,RSSurfaceNodeAbilityState abilityState)143 std::tuple<bool, bool, bool> RSAnimationManager::Animate(
144     int64_t time, int64_t& minLeftDelayTime, bool nodeIsOnTheTree, RSSurfaceNodeAbilityState abilityState)
145 {
146     // process animation
147     bool hasRunningAnimation = false;
148     bool needRequestNextVsync = false;
149     // isCalculateAnimationValue is embedded modify for stat animate frame drop
150     bool isCalculateAnimationValue = false;
151     rsRange_.Reset();
152     rateDecider_.Reset();
153     // iterate and execute all animations, remove finished animations
154     EraseIf(animations_, [this, &hasRunningAnimation, time, &needRequestNextVsync, nodeIsOnTheTree,
155         &isCalculateAnimationValue, abilityState, &minLeftDelayTime](auto& iter) -> bool {
156         auto& animation = iter.second;
157         // infinite iteration animation out of the tree or in the background does not request vsync
158         if ((!nodeIsOnTheTree || abilityState == RSSurfaceNodeAbilityState::BACKGROUND) &&
159             animation->GetRepeatCount() == -1) {
160             hasRunningAnimation = animation->IsRunning() || hasRunningAnimation;
161             return false;
162         }
163         // finite iteration animation in the background finished immediately
164         if (abilityState == RSSurfaceNodeAbilityState::BACKGROUND) {
165             RSAnimationTraceUtils::GetInstance().AddAnimationFinishTrace(
166                 "Animation finish background", animation->GetTargetId(), animation->GetAnimationId(), false);
167             animation->Finish();
168         }
169         bool isFinished = animation->Animate(time, minLeftDelayTime);
170         if (isFinished) {
171             isCalculateAnimationValue = true;
172             OnAnimationFinished(animation);
173         } else {
174             hasRunningAnimation = animation->IsRunning() || hasRunningAnimation;
175             needRequestNextVsync = animation->IsRunning() || needRequestNextVsync;
176             isCalculateAnimationValue = animation->IsCalculateAniamtionValue() || isCalculateAnimationValue;
177 
178             auto range = animation->GetFrameRateRange();
179             if (range.IsValid()) {
180                 rsRange_.Merge(range);
181             }
182             RS_OPTIONAL_TRACE_BEGIN("AddDecisionElement property id: [" + std::to_string(animation->GetPropertyId()) +
183                 "], animation id: [" + std::to_string(animation->GetAnimationId()) + "]");
184             rateDecider_.AddDecisionElement(animation->GetPropertyId(), animation->GetAnimateVelocity(), range);
185             RS_OPTIONAL_TRACE_END();
186         }
187         return isFinished;
188     });
189     rateDecider_.MakeDecision(frameRateGetFunc_);
190     isCalculateAnimationValue = isCalculateAnimationValue && nodeIsOnTheTree;
191 
192     return { hasRunningAnimation, needRequestNextVsync, isCalculateAnimationValue };
193 }
194 
SetRateDeciderEnable(bool enabled,const FrameRateGetFunc & func)195 void RSAnimationManager::SetRateDeciderEnable(bool enabled, const FrameRateGetFunc& func)
196 {
197     rateDecider_.SetEnable(enabled);
198     frameRateGetFunc_ = func;
199 }
200 
SetRateDeciderSize(float width,float height)201 void RSAnimationManager::SetRateDeciderSize(float width, float height)
202 {
203     rateDecider_.SetNodeSize(width, height);
204 }
205 
SetRateDeciderScale(float scaleX,float scaleY)206 void RSAnimationManager::SetRateDeciderScale(float scaleX, float scaleY)
207 {
208     rateDecider_.SetNodeScale(scaleX, scaleY);
209 }
210 
SetRateDeciderAbsRect(int32_t width,int32_t height)211 void RSAnimationManager::SetRateDeciderAbsRect(int32_t width, int32_t height)
212 {
213     rateDecider_.SetAbsRect(width, height);
214 }
215 
GetDecideFrameRateRange() const216 const FrameRateRange& RSAnimationManager::GetDecideFrameRateRange() const
217 {
218     return rateDecider_.GetFrameRateRange();
219 }
220 
GetFrameRateRange() const221 const FrameRateRange& RSAnimationManager::GetFrameRateRange() const
222 {
223     return rsRange_;
224 }
225 
GetAnimation(AnimationId id) const226 const std::shared_ptr<RSRenderAnimation> RSAnimationManager::GetAnimation(AnimationId id) const
227 {
228     auto animationItr = animations_.find(id);
229     if (animationItr == animations_.end()) {
230         ROSEN_LOGD("RSAnimationManager::GetAnimation, animation [%{public}" PRIu64 "] not found", id);
231         return nullptr;
232     }
233     return animationItr->second;
234 }
235 
OnAnimationFinished(const std::shared_ptr<RSRenderAnimation> & animation)236 void RSAnimationManager::OnAnimationFinished(const std::shared_ptr<RSRenderAnimation>& animation)
237 {
238     NodeId targetId = animation->GetTargetId();
239     AnimationId animationId = animation->GetAnimationId();
240     uint64_t token = animation->GetToken();
241 
242     RSAnimationTraceUtils::GetInstance().AddAnimationFinishTrace(
243         "Animation Send Finish", targetId, animationId, false);
244     std::unique_ptr<RSCommand> command =
245         std::make_unique<RSAnimationCallback>(targetId, animationId, token, FINISHED);
246     RSMessageProcessor::Instance().AddUIMessage(ExtractPid(animationId), command);
247     animation->Detach();
248 }
249 
RegisterSpringAnimation(PropertyId propertyId,AnimationId animId)250 void RSAnimationManager::RegisterSpringAnimation(PropertyId propertyId, AnimationId animId)
251 {
252     springAnimations_[propertyId] = animId;
253 }
254 
UnregisterSpringAnimation(PropertyId propertyId,AnimationId animId)255 void RSAnimationManager::UnregisterSpringAnimation(PropertyId propertyId, AnimationId animId)
256 {
257     auto it = springAnimations_.find(propertyId);
258     if (it != springAnimations_.end() && it->second == animId) {
259         springAnimations_.erase(it);
260     }
261 }
262 
QuerySpringAnimation(PropertyId propertyId)263 std::shared_ptr<RSRenderAnimation> RSAnimationManager::QuerySpringAnimation(PropertyId propertyId)
264 {
265     auto it = springAnimations_.find(propertyId);
266     if (it == springAnimations_.end() || it->second == 0) {
267         return nullptr;
268     }
269     return GetAnimation(it->second);
270 }
271 
RegisterPathAnimation(PropertyId propertyId,AnimationId animId)272 void RSAnimationManager::RegisterPathAnimation(PropertyId propertyId, AnimationId animId)
273 {
274     pathAnimations_[propertyId] = animId;
275 }
276 
UnregisterPathAnimation(PropertyId propertyId,AnimationId animId)277 void RSAnimationManager::UnregisterPathAnimation(PropertyId propertyId, AnimationId animId)
278 {
279     auto it = pathAnimations_.find(propertyId);
280     if (it != pathAnimations_.end() && it->second == animId) {
281         pathAnimations_.erase(it);
282     }
283 }
284 
QueryPathAnimation(PropertyId propertyId)285 std::shared_ptr<RSRenderAnimation> RSAnimationManager::QueryPathAnimation(PropertyId propertyId)
286 {
287     auto it = pathAnimations_.find(propertyId);
288     if (it == pathAnimations_.end() || it->second == 0) {
289         return nullptr;
290     }
291     return GetAnimation(it->second);
292 }
293 
RegisterParticleAnimation(PropertyId propertyId,AnimationId animId)294 void RSAnimationManager::RegisterParticleAnimation(PropertyId propertyId, AnimationId animId)
295 {
296     particleAnimations_[propertyId] = animId;
297 }
298 
UnregisterParticleAnimation(PropertyId propertyId,AnimationId animId)299 void RSAnimationManager::UnregisterParticleAnimation(PropertyId propertyId, AnimationId animId)
300 {
301     auto it = particleAnimations_.find(propertyId);
302     if (it != particleAnimations_.end() && it->second == animId) {
303         particleAnimations_.erase(it);
304     }
305 }
306 
GetParticleAnimations()307 const std::unordered_map<PropertyId, AnimationId>& RSAnimationManager::GetParticleAnimations()
308 {
309     return particleAnimations_;
310 }
311 
GetParticleAnimation()312 std::shared_ptr<RSRenderAnimation> RSAnimationManager::GetParticleAnimation()
313 {
314     if (particleAnimations_.empty()) {
315         return nullptr;
316     }
317     return GetAnimation(particleAnimations_.begin()->second);
318 }
319 } // namespace Rosen
320 } // namespace OHOS
321