1 
2 /*
3  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "modifier/rs_modifier_manager.h"
18 
19 #include "animation/rs_animation_trace_utils.h"
20 #include "animation/rs_render_animation.h"
21 #include "command/rs_animation_command.h"
22 #include "command/rs_message_processor.h"
23 #include "modifier/rs_property_modifier.h"
24 #include "platform/common/rs_log.h"
25 #include "rs_trace.h"
26 
27 namespace OHOS {
28 namespace Rosen {
AddModifier(const std::shared_ptr<RSModifier> & modifier)29 void RSModifierManager::AddModifier(const std::shared_ptr<RSModifier>& modifier)
30 {
31     modifiers_.insert(modifier);
32 }
33 
Draw()34 void RSModifierManager::Draw()
35 {
36     if (modifiers_.empty()) {
37         return;
38     }
39 
40     RS_TRACE_NAME("RSModifierManager Draw num:[" + std::to_string(modifiers_.size()) + "]");
41     for (auto& modifier : modifiers_) {
42         RS_TRACE_NAME("RSModifier::Draw");
43         modifier->UpdateToRender();
44         modifier->SetDirty(false);
45         modifier->ResetRSNodeExtendModifierDirty();
46     }
47     modifiers_.clear();
48 }
49 
AddAnimation(const std::shared_ptr<RSRenderAnimation> & animation)50 void RSModifierManager::AddAnimation(const std::shared_ptr<RSRenderAnimation>& animation)
51 {
52     AnimationId key = animation->GetAnimationId();
53     if (animations_.find(key) != animations_.end()) {
54         ROSEN_LOGE("RSModifierManager::AddAnimation, The animation already exists when is added");
55         return;
56     }
57     animations_.emplace(key, animation);
58 
59     std::shared_ptr<RSRenderDisplaySync> displaySync = std::make_shared<RSRenderDisplaySync>(animation);
60     displaySync->SetExpectedFrameRateRange(animation->GetFrameRateRange());
61     displaySyncs_.emplace(key, displaySync);
62 }
63 
RemoveAnimation(AnimationId keyId)64 void RSModifierManager::RemoveAnimation(AnimationId keyId)
65 {
66     auto animationItr = animations_.find(keyId);
67     if (animationItr == animations_.end()) {
68         ROSEN_LOGE("RSModifierManager::RemoveAnimation, The Animation does not exist when is deleted");
69         return;
70     }
71     animations_.erase(animationItr);
72     displaySyncs_.erase(keyId);
73 }
74 
HasUIRunningAnimation()75 bool RSModifierManager::HasUIRunningAnimation()
76 {
77     for (auto& iter : animations_) {
78         auto animation = iter.second.lock();
79         if (animation && animation->IsRunning()) {
80             return true;
81         }
82     }
83     return false;
84 }
85 
Animate(int64_t time,int64_t vsyncPeriod)86 bool RSModifierManager::Animate(int64_t time, int64_t vsyncPeriod)
87 {
88     RS_TRACE_NAME_FMT("RunningCustomAnimation num:[%d] time:[%lld]", animations_.size(), time);
89     // process animation
90     bool hasRunningAnimation = false;
91     rateDecider_.Reset();
92 
93     // iterate and execute all animations, remove finished animations
94     EraseIf(animations_, [this, &hasRunningAnimation, time, vsyncPeriod](auto& iter) -> bool {
95         auto animation = iter.second.lock();
96         if (animation == nullptr) {
97             displaySyncs_.erase(iter.first);
98             return true;
99         }
100 
101         bool isFinished = false;
102         AnimationId animId = animation->GetAnimationId();
103         if (!JudgeAnimateWhetherSkip(animId, time, vsyncPeriod)) {
104             isFinished = animation->Animate(time);
105         }
106 
107         if (isFinished) {
108             OnAnimationFinished(animation);
109         } else {
110             hasRunningAnimation = animation->IsRunning() || hasRunningAnimation;
111             rateDecider_.AddDecisionElement(animation->GetPropertyId(),
112                 animation->GetAnimateVelocity(), animation->GetFrameRateRange());
113         }
114         return isFinished;
115     });
116     rateDecider_.MakeDecision(frameRateGetFunc_);
117 
118     return hasRunningAnimation;
119 }
120 
FlushStartAnimation(int64_t time)121 void RSModifierManager::FlushStartAnimation(int64_t time)
122 {
123     for (auto& iter : animations_) {
124         auto animation = iter.second.lock();
125         if (animation && animation->GetNeedUpdateStartTime()) {
126             animation->SetStartTime(time);
127         }
128     }
129 }
130 
JudgeAnimateWhetherSkip(AnimationId animId,int64_t time,int64_t vsyncPeriod)131 bool RSModifierManager::JudgeAnimateWhetherSkip(AnimationId animId, int64_t time, int64_t vsyncPeriod)
132 {
133     bool isSkip = false;
134     if (!displaySyncs_.count(animId)) {
135         return isSkip;
136     }
137 
138     auto displaySync = displaySyncs_[animId];
139     if (displaySync) {
140         isSkip = displaySync->OnFrameSkip(time, vsyncPeriod, IsDisplaySyncEnabled());
141     }
142 
143     return isSkip;
144 }
145 
SetFrameRateGetFunc(const FrameRateGetFunc & func)146 void RSModifierManager::SetFrameRateGetFunc(const FrameRateGetFunc& func)
147 {
148     frameRateGetFunc_ = func;
149 }
150 
GetFrameRateRange() const151 const FrameRateRange RSModifierManager::GetFrameRateRange() const
152 {
153     auto frameRateRange = rateDecider_.GetFrameRateRange();
154     frameRateRange.type_ = UI_ANIMATION_FRAME_RATE_TYPE;
155     return frameRateRange;
156 }
157 
OnAnimationFinished(const std::shared_ptr<RSRenderAnimation> & animation)158 void RSModifierManager::OnAnimationFinished(const std::shared_ptr<RSRenderAnimation>& animation)
159 {
160     NodeId targetId = animation->GetTargetId();
161     AnimationId animationId = animation->GetAnimationId();
162     displaySyncs_.erase(animationId);
163 
164     RSAnimationTraceUtils::GetInstance().addAnimationFinishTrace(
165         "Animation Send Finish", targetId, animationId, false);
166     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCallback>(targetId, animationId, FINISHED);
167     RSMessageProcessor::Instance().AddUIMessage(ExtractPid(animationId), command);
168 
169     animation->Detach();
170 }
171 
RegisterSpringAnimation(PropertyId propertyId,AnimationId animId)172 void RSModifierManager::RegisterSpringAnimation(PropertyId propertyId, AnimationId animId)
173 {
174     springAnimations_[propertyId] = animId;
175 }
176 
UnregisterSpringAnimation(PropertyId propertyId,AnimationId animId)177 void RSModifierManager::UnregisterSpringAnimation(PropertyId propertyId, AnimationId animId)
178 {
179     auto it = springAnimations_.find(propertyId);
180     if (it != springAnimations_.end() && it->second == animId) {
181         springAnimations_.erase(it);
182     }
183 }
184 
QuerySpringAnimation(PropertyId propertyId)185 std::shared_ptr<RSRenderAnimation> RSModifierManager::QuerySpringAnimation(PropertyId propertyId)
186 {
187     auto it = springAnimations_.find(propertyId);
188     if (it == springAnimations_.end() || it->second == 0) {
189         ROSEN_LOGD("RSModifierManager::QuerySpringAnimation: there is no spring animation on the current property.");
190         return nullptr;
191     }
192     return GetAnimation(it->second);
193 }
194 
GetAnimation(AnimationId id) const195 const std::shared_ptr<RSRenderAnimation> RSModifierManager::GetAnimation(AnimationId id) const
196 {
197     auto animationItr = animations_.find(id);
198     if (animationItr == animations_.end()) {
199         ROSEN_LOGD("RSModifierManager::GetAnimation, animation [%{public}" PRIu64 "] not found", id);
200         return nullptr;
201     }
202     return animationItr->second.lock();
203 }
204 
SetDisplaySyncEnable(bool isDisplaySyncEnabled)205 void RSModifierManager::SetDisplaySyncEnable(bool isDisplaySyncEnabled)
206 {
207     isDisplaySyncEnabled_ = isDisplaySyncEnabled;
208 }
209 
IsDisplaySyncEnabled() const210 bool RSModifierManager::IsDisplaySyncEnabled() const
211 {
212     return isDisplaySyncEnabled_;
213 }
214 } // namespace Rosen
215 } // namespace OHOS
216