• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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