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 "rs_trace.h"
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 "modifier_ng/custom/rs_custom_modifier.h"
26 #include "platform/common/rs_log.h"
27
28 namespace OHOS {
29 namespace Rosen {
AddModifier(const std::shared_ptr<Modifier> & modifier)30 void RSModifierManager::AddModifier(const std::shared_ptr<Modifier>& modifier)
31 {
32 modifiers_.insert(modifier);
33 }
34
Draw()35 void RSModifierManager::Draw()
36 {
37 if (!modifiers_.empty()) {
38 RS_TRACE_NAME("RSModifierManager Draw num:[" + std::to_string(modifiers_.size()) + "]");
39 for (auto& modifier : modifiers_) {
40 RS_TRACE_NAME("RSModifier::Draw");
41 modifier->UpdateToRender();
42 modifier->SetDirty(false);
43 modifier->ResetRSNodeExtendModifierDirty();
44 }
45 modifiers_.clear();
46 }
47 }
48
AddAnimation(const std::shared_ptr<RSRenderAnimation> & animation)49 void RSModifierManager::AddAnimation(const std::shared_ptr<RSRenderAnimation>& animation)
50 {
51 if (animation == nullptr) {
52 ROSEN_LOGE("RSModifierManager::AddAnimation animation is nullptr");
53 return;
54 }
55
56 AnimationId key = animation->GetAnimationId();
57 if (animations_.find(key) != animations_.end()) {
58 ROSEN_LOGE("RSModifierManager::AddAnimation, The animation already exists when is added");
59 return;
60 }
61 animations_.emplace(key, animation);
62 hasFirstFrameAnimation_ = true;
63
64 std::shared_ptr<RSRenderDisplaySync> displaySync = std::make_shared<RSRenderDisplaySync>(animation);
65 displaySync->SetExpectedFrameRateRange(animation->GetFrameRateRange());
66 displaySyncs_.emplace(key, displaySync);
67 }
68
RemoveAnimation(AnimationId keyId)69 void RSModifierManager::RemoveAnimation(AnimationId keyId)
70 {
71 auto animationItr = animations_.find(keyId);
72 if (animationItr == animations_.end()) {
73 ROSEN_LOGE("RSModifierManager::RemoveAnimation, The Animation does not exist when is deleted");
74 return;
75 }
76 animations_.erase(animationItr);
77 displaySyncs_.erase(keyId);
78 }
79
HasUIRunningAnimation()80 bool RSModifierManager::HasUIRunningAnimation()
81 {
82 for (auto& iter : animations_) {
83 auto animation = iter.second.lock();
84 if (animation && animation->IsRunning()) {
85 return true;
86 }
87 }
88 return false;
89 }
90
Animate(int64_t time,int64_t vsyncPeriod)91 bool RSModifierManager::Animate(int64_t time, int64_t vsyncPeriod)
92 {
93 RS_TRACE_NAME_FMT("RunningCustomAnimation num:[%d] time:[%lld]", animations_.size(), time);
94 // process animation
95 bool hasRunningAnimation = false;
96 rateDecider_.Reset();
97 // For now, there is no need to optimize the power consumption issue related to delayTime.
98 int64_t minLeftDelayTime = 0;
99
100 // iterate and execute all animations, remove finished animations
101 EraseIf(animations_, [this, &hasRunningAnimation, time, vsyncPeriod, &minLeftDelayTime](auto& iter) -> bool {
102 auto animation = iter.second.lock();
103 if (animation == nullptr) {
104 displaySyncs_.erase(iter.first);
105 return true;
106 }
107
108 bool isFinished = false;
109 AnimationId animId = animation->GetAnimationId();
110 if (!JudgeAnimateWhetherSkip(animId, time, vsyncPeriod)) {
111 isFinished = animation->Animate(time, minLeftDelayTime);
112 }
113
114 if (isFinished) {
115 OnAnimationFinished(animation);
116 } else {
117 hasRunningAnimation = animation->IsRunning() || hasRunningAnimation;
118 rateDecider_.AddDecisionElement(animation->GetPropertyId(),
119 animation->GetAnimateVelocity(), animation->GetFrameRateRange());
120 }
121 return isFinished;
122 });
123 rateDecider_.MakeDecision(frameRateGetFunc_);
124
125 return hasRunningAnimation;
126 }
127
GetAndResetFirstFrameAnimationState()128 bool RSModifierManager::GetAndResetFirstFrameAnimationState()
129 {
130 // UI animation need this info to get expected frame rate, each window will call it once per frame
131 return std::exchange(hasFirstFrameAnimation_, false);
132 }
133
FlushStartAnimation(int64_t time)134 void RSModifierManager::FlushStartAnimation(int64_t time)
135 {
136 for (auto& iter : animations_) {
137 auto animation = iter.second.lock();
138 if (animation && animation->GetNeedUpdateStartTime()) {
139 animation->SetStartTime(time);
140 }
141 }
142 }
143
JudgeAnimateWhetherSkip(AnimationId animId,int64_t time,int64_t vsyncPeriod)144 bool RSModifierManager::JudgeAnimateWhetherSkip(AnimationId animId, int64_t time, int64_t vsyncPeriod)
145 {
146 bool isSkip = false;
147 if (!displaySyncs_.count(animId)) {
148 return isSkip;
149 }
150
151 auto displaySync = displaySyncs_[animId];
152 if (displaySync) {
153 isSkip = displaySync->OnFrameSkip(time, vsyncPeriod, IsDisplaySyncEnabled());
154 }
155
156 return isSkip;
157 }
158
SetFrameRateGetFunc(const FrameRateGetFunc & func)159 void RSModifierManager::SetFrameRateGetFunc(const FrameRateGetFunc& func)
160 {
161 frameRateGetFunc_ = func;
162 }
163
GetFrameRateRange() const164 const FrameRateRange RSModifierManager::GetFrameRateRange() const
165 {
166 auto frameRateRange = rateDecider_.GetFrameRateRange();
167 frameRateRange.type_ = UI_ANIMATION_FRAME_RATE_TYPE;
168 return frameRateRange;
169 }
170
OnAnimationFinished(const std::shared_ptr<RSRenderAnimation> & animation)171 void RSModifierManager::OnAnimationFinished(const std::shared_ptr<RSRenderAnimation>& animation)
172 {
173 NodeId targetId = animation->GetTargetId();
174 AnimationId animationId = animation->GetAnimationId();
175 uint64_t token = animation->GetToken();
176 displaySyncs_.erase(animationId);
177
178 RSAnimationTraceUtils::GetInstance().AddAnimationFinishTrace(
179 "Animation Send Finish", targetId, animationId, false);
180 std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCallback>(targetId, animationId, token, FINISHED);
181 RSMessageProcessor::Instance().AddUIMessage(ExtractPid(animationId), command);
182
183 animation->Detach();
184 }
185
RegisterSpringAnimation(PropertyId propertyId,AnimationId animId)186 void RSModifierManager::RegisterSpringAnimation(PropertyId propertyId, AnimationId animId)
187 {
188 springAnimations_[propertyId] = animId;
189 }
190
UnregisterSpringAnimation(PropertyId propertyId,AnimationId animId)191 void RSModifierManager::UnregisterSpringAnimation(PropertyId propertyId, AnimationId animId)
192 {
193 auto it = springAnimations_.find(propertyId);
194 if (it != springAnimations_.end() && it->second == animId) {
195 springAnimations_.erase(it);
196 }
197 }
198
QuerySpringAnimation(PropertyId propertyId)199 std::shared_ptr<RSRenderAnimation> RSModifierManager::QuerySpringAnimation(PropertyId propertyId)
200 {
201 auto it = springAnimations_.find(propertyId);
202 if (it == springAnimations_.end() || it->second == 0) {
203 ROSEN_LOGD("RSModifierManager::QuerySpringAnimation: there is no spring animation on the current property.");
204 return nullptr;
205 }
206 return GetAnimation(it->second);
207 }
208
GetAnimation(AnimationId id) const209 const std::shared_ptr<RSRenderAnimation> RSModifierManager::GetAnimation(AnimationId id) const
210 {
211 auto animationItr = animations_.find(id);
212 if (animationItr == animations_.end()) {
213 ROSEN_LOGD("RSModifierManager::GetAnimation, animation [%{public}" PRIu64 "] not found", id);
214 return nullptr;
215 }
216 return animationItr->second.lock();
217 }
218
SetDisplaySyncEnable(bool isDisplaySyncEnabled)219 void RSModifierManager::SetDisplaySyncEnable(bool isDisplaySyncEnabled)
220 {
221 isDisplaySyncEnabled_ = isDisplaySyncEnabled;
222 }
223
IsDisplaySyncEnabled() const224 bool RSModifierManager::IsDisplaySyncEnabled() const
225 {
226 return isDisplaySyncEnabled_;
227 }
228 } // namespace Rosen
229 } // namespace OHOS
230