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