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 hasFirstFrameAnimation_ = true;
59
60 std::shared_ptr<RSRenderDisplaySync> displaySync = std::make_shared<RSRenderDisplaySync>(animation);
61 displaySync->SetExpectedFrameRateRange(animation->GetFrameRateRange());
62 displaySyncs_.emplace(key, displaySync);
63 }
64
RemoveAnimation(AnimationId keyId)65 void RSModifierManager::RemoveAnimation(AnimationId keyId)
66 {
67 auto animationItr = animations_.find(keyId);
68 if (animationItr == animations_.end()) {
69 ROSEN_LOGE("RSModifierManager::RemoveAnimation, The Animation does not exist when is deleted");
70 return;
71 }
72 animations_.erase(animationItr);
73 displaySyncs_.erase(keyId);
74 }
75
HasUIRunningAnimation()76 bool RSModifierManager::HasUIRunningAnimation()
77 {
78 for (auto& iter : animations_) {
79 auto animation = iter.second.lock();
80 if (animation && animation->IsRunning()) {
81 return true;
82 }
83 }
84 return false;
85 }
86
Animate(int64_t time,int64_t vsyncPeriod)87 bool RSModifierManager::Animate(int64_t time, int64_t vsyncPeriod)
88 {
89 RS_TRACE_NAME_FMT("RunningCustomAnimation num:[%d] time:[%lld]", animations_.size(), time);
90 // process animation
91 bool hasRunningAnimation = false;
92 rateDecider_.Reset();
93
94 // iterate and execute all animations, remove finished animations
95 EraseIf(animations_, [this, &hasRunningAnimation, time, vsyncPeriod](auto& iter) -> bool {
96 auto animation = iter.second.lock();
97 if (animation == nullptr) {
98 displaySyncs_.erase(iter.first);
99 return true;
100 }
101
102 bool isFinished = false;
103 AnimationId animId = animation->GetAnimationId();
104 if (!JudgeAnimateWhetherSkip(animId, time, vsyncPeriod)) {
105 isFinished = animation->Animate(time);
106 }
107
108 if (isFinished) {
109 OnAnimationFinished(animation);
110 } else {
111 hasRunningAnimation = animation->IsRunning() || hasRunningAnimation;
112 rateDecider_.AddDecisionElement(animation->GetPropertyId(),
113 animation->GetAnimateVelocity(), animation->GetFrameRateRange());
114 }
115 return isFinished;
116 });
117 rateDecider_.MakeDecision(frameRateGetFunc_);
118
119 return hasRunningAnimation;
120 }
121
GetAndResetFirstFrameAnimationState()122 bool RSModifierManager::GetAndResetFirstFrameAnimationState()
123 {
124 // UI animation need this info to get expected frame rate, each window will call it once per frame
125 return std::exchange(hasFirstFrameAnimation_, false);
126 }
127
FlushStartAnimation(int64_t time)128 void RSModifierManager::FlushStartAnimation(int64_t time)
129 {
130 for (auto& iter : animations_) {
131 auto animation = iter.second.lock();
132 if (animation && animation->GetNeedUpdateStartTime()) {
133 animation->SetStartTime(time);
134 }
135 }
136 }
137
JudgeAnimateWhetherSkip(AnimationId animId,int64_t time,int64_t vsyncPeriod)138 bool RSModifierManager::JudgeAnimateWhetherSkip(AnimationId animId, int64_t time, int64_t vsyncPeriod)
139 {
140 bool isSkip = false;
141 if (!displaySyncs_.count(animId)) {
142 return isSkip;
143 }
144
145 auto displaySync = displaySyncs_[animId];
146 if (displaySync) {
147 isSkip = displaySync->OnFrameSkip(time, vsyncPeriod, IsDisplaySyncEnabled());
148 }
149
150 return isSkip;
151 }
152
SetFrameRateGetFunc(const FrameRateGetFunc & func)153 void RSModifierManager::SetFrameRateGetFunc(const FrameRateGetFunc& func)
154 {
155 frameRateGetFunc_ = func;
156 }
157
GetFrameRateRange() const158 const FrameRateRange RSModifierManager::GetFrameRateRange() const
159 {
160 auto frameRateRange = rateDecider_.GetFrameRateRange();
161 frameRateRange.type_ = UI_ANIMATION_FRAME_RATE_TYPE;
162 return frameRateRange;
163 }
164
OnAnimationFinished(const std::shared_ptr<RSRenderAnimation> & animation)165 void RSModifierManager::OnAnimationFinished(const std::shared_ptr<RSRenderAnimation>& animation)
166 {
167 NodeId targetId = animation->GetTargetId();
168 AnimationId animationId = animation->GetAnimationId();
169 uint64_t token = animation->GetToken();
170 displaySyncs_.erase(animationId);
171
172 RSAnimationTraceUtils::GetInstance().addAnimationFinishTrace(
173 "Animation Send Finish", targetId, animationId, false);
174 std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCallback>(targetId, animationId, token, FINISHED);
175 RSMessageProcessor::Instance().AddUIMessage(ExtractPid(animationId), command);
176
177 animation->Detach();
178 }
179
RegisterSpringAnimation(PropertyId propertyId,AnimationId animId)180 void RSModifierManager::RegisterSpringAnimation(PropertyId propertyId, AnimationId animId)
181 {
182 springAnimations_[propertyId] = animId;
183 }
184
UnregisterSpringAnimation(PropertyId propertyId,AnimationId animId)185 void RSModifierManager::UnregisterSpringAnimation(PropertyId propertyId, AnimationId animId)
186 {
187 auto it = springAnimations_.find(propertyId);
188 if (it != springAnimations_.end() && it->second == animId) {
189 springAnimations_.erase(it);
190 }
191 }
192
QuerySpringAnimation(PropertyId propertyId)193 std::shared_ptr<RSRenderAnimation> RSModifierManager::QuerySpringAnimation(PropertyId propertyId)
194 {
195 auto it = springAnimations_.find(propertyId);
196 if (it == springAnimations_.end() || it->second == 0) {
197 ROSEN_LOGD("RSModifierManager::QuerySpringAnimation: there is no spring animation on the current property.");
198 return nullptr;
199 }
200 return GetAnimation(it->second);
201 }
202
GetAnimation(AnimationId id) const203 const std::shared_ptr<RSRenderAnimation> RSModifierManager::GetAnimation(AnimationId id) const
204 {
205 auto animationItr = animations_.find(id);
206 if (animationItr == animations_.end()) {
207 ROSEN_LOGD("RSModifierManager::GetAnimation, animation [%{public}" PRIu64 "] not found", id);
208 return nullptr;
209 }
210 return animationItr->second.lock();
211 }
212
SetDisplaySyncEnable(bool isDisplaySyncEnabled)213 void RSModifierManager::SetDisplaySyncEnable(bool isDisplaySyncEnabled)
214 {
215 isDisplaySyncEnabled_ = isDisplaySyncEnabled;
216 }
217
IsDisplaySyncEnabled() const218 bool RSModifierManager::IsDisplaySyncEnabled() const
219 {
220 return isDisplaySyncEnabled_;
221 }
222 } // namespace Rosen
223 } // namespace OHOS
224