• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "animation/rs_animation_fraction.h"
17 
18 #include <cstdlib>
19 #include <cstring>
20 #include <string>
21 
22 #include "common/rs_common_def.h"
23 #include "platform/common/rs_log.h"
24 #include "platform/common/rs_system_properties.h"
25 
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 static constexpr int INFINITE = -1;
30 static constexpr int64_t MS_TO_NS = 1000000;
31 static constexpr int REVERSE_COUNT = 2;
32 static constexpr int MAX_SPEED = 1000000;
33 constexpr const char* ANIMATION_SCALE_NAME = "persist.sys.graphic.animationscale";
34 } // namespace
35 
36 bool RSAnimationFraction::isInited_ = false;
37 float RSAnimationFraction::animationScale_ = 1.0f;
38 std::mutex RSAnimationFraction::mutex_;
39 
RSAnimationFraction()40 RSAnimationFraction::RSAnimationFraction()
41 {
42     currentIsReverseCycle_ = !isForward_;
43 }
44 
Init()45 void RSAnimationFraction::Init()
46 {
47     if (!isInited_) {
48         SetAnimationScale(RSSystemProperties::GetAnimationScale());
49         RSSystemProperties::WatchSystemProperty(ANIMATION_SCALE_NAME, OnAnimationScaleChangedCallback, nullptr);
50         isInited_ = true;
51     }
52 }
53 
GetAnimationScale()54 float RSAnimationFraction::GetAnimationScale()
55 {
56     std::lock_guard<std::mutex> lock(mutex_);
57     return animationScale_;
58 }
59 
SetAnimationScale(float animationScale)60 void RSAnimationFraction::SetAnimationScale(float animationScale)
61 {
62     std::lock_guard<std::mutex> lock(mutex_);
63     animationScale_ = animationScale < 0.0 ? 0.0 : animationScale;
64 }
65 
OnAnimationScaleChangedCallback(const char * key,const char * value,void * context)66 void RSAnimationFraction::OnAnimationScaleChangedCallback(const char *key, const char *value, void *context)
67 {
68     if (strcmp(key, ANIMATION_SCALE_NAME) != 0) {
69         return;
70     }
71     float animationScale = std::atof(value);
72     SetAnimationScale(animationScale);
73 }
74 
SetDirectionAfterStart(const ForwardDirection & direction)75 void RSAnimationFraction::SetDirectionAfterStart(const ForwardDirection& direction)
76 {
77     direction_ = direction;
78 }
79 
SetLastFrameTime(int64_t lastFrameTime)80 void RSAnimationFraction::SetLastFrameTime(int64_t lastFrameTime)
81 {
82     lastFrameTime_ = lastFrameTime;
83 }
84 
GetLastFrameTime() const85 int64_t RSAnimationFraction::GetLastFrameTime() const
86 {
87     return lastFrameTime_;
88 }
89 
GetAnimationFraction(int64_t time,bool & isInstartDelay,bool & isFinished)90 float RSAnimationFraction::GetAnimationFraction(int64_t time, bool& isInstartDelay, bool& isFinished)
91 {
92     int64_t durationNs = duration_ * MS_TO_NS;
93     int64_t startDelayNs = startDelay_ * MS_TO_NS;
94     int64_t deltaTime = time - lastFrameTime_;
95     lastFrameTime_ = time;
96     isInstartDelay = false;
97     if (durationNs <= 0 || (repeatCount_ <= 0 && repeatCount_ != INFINITE)) {
98         isFinished = true;
99         return GetEndFraction();
100     }
101     // 1. Calculates the total running fraction of animation
102     float animationScale = GetAnimationScale();
103     if (direction_ == ForwardDirection::NORMAL) {
104         if (animationScale == 0.0) {
105             runningTime_ += static_cast<int64_t>(deltaTime * MAX_SPEED);
106         } else {
107             runningTime_ += static_cast<int64_t>(deltaTime * speed_ / animationScale);
108         }
109     } else {
110         if (animationScale == 0.0) {
111             runningTime_ -= static_cast<int64_t>(deltaTime * MAX_SPEED);
112         } else {
113             runningTime_ -= static_cast<int64_t>(deltaTime * speed_ / animationScale);
114         }
115     }
116     if (runningTime_ < startDelayNs) {
117         isFinished = IsFinished();
118         isInstartDelay = isFinished ? false : true;
119         return GetStartFraction();
120     }
121 
122     // 2. Calculate the running time of the current cycle animation.
123     int64_t realPlayTime = runningTime_ - startDelayNs - (curRepeatCount_ * durationNs);
124 
125     // 3. Update the number of cycles and the corresponding animation fraction.
126     if (direction_ == ForwardDirection::NORMAL) {
127         curRepeatCount_ += realPlayTime / durationNs;
128     } else {
129         while (curRepeatCount_ > 0 && realPlayTime < 0) {
130             curRepeatCount_--;
131             realPlayTime += durationNs;
132         }
133     }
134     playTime_ = realPlayTime % durationNs;
135 
136     // 4. update status for auto reverse
137     isFinished = IsFinished();
138     UpdateReverseState(isFinished);
139 
140     // 5. get final animation fraction
141     if (isFinished) {
142         return GetEndFraction();
143     }
144     curTimeFraction_ = static_cast<float>(playTime_) / durationNs;
145     curTimeFraction_ = currentIsReverseCycle_ ? (1.0f - curTimeFraction_) : curTimeFraction_;
146     curTimeFraction_ = std::min(std::max(curTimeFraction_, 0.0f), 1.0f);
147     return curTimeFraction_;
148 }
149 
IsFinished() const150 bool RSAnimationFraction::IsFinished() const
151 {
152     if (direction_ == ForwardDirection::NORMAL) {
153         if (repeatCount_ == INFINITE) {
154             return false;
155         }
156         int64_t totalDuration = (duration_ * repeatCount_ + startDelay_) * MS_TO_NS;
157         return runningTime_ >= totalDuration;
158     } else {
159         return runningTime_ <= 0;
160     }
161 }
162 
GetStartFraction() const163 float RSAnimationFraction::GetStartFraction() const
164 {
165     return isForward_ ? 0.0f : 1.0f;
166 }
167 
GetEndFraction() const168 float RSAnimationFraction::GetEndFraction() const
169 {
170     float endFraction = 1.0f;
171     if ((autoReverse_ && repeatCount_ % REVERSE_COUNT == 0) || direction_ == ForwardDirection::REVERSE) {
172         endFraction = 0.0f;
173     }
174     endFraction = isForward_ ? endFraction : 1.0 - endFraction;
175     return endFraction;
176 }
177 
UpdateReverseState(bool finish)178 void RSAnimationFraction::UpdateReverseState(bool finish)
179 {
180     if (isForward_) {
181         if (!autoReverse_) {
182             currentIsReverseCycle_ = false;
183             return;
184         }
185         currentIsReverseCycle_ =
186             finish ? (curRepeatCount_ % REVERSE_COUNT == 0) : (curRepeatCount_ % REVERSE_COUNT == 1);
187     } else {
188         if (!autoReverse_) {
189             currentIsReverseCycle_ = true;
190             return;
191         }
192         currentIsReverseCycle_ =
193             finish ? (curRepeatCount_ % REVERSE_COUNT == 1) : (curRepeatCount_ % REVERSE_COUNT == 0);
194     }
195 }
196 
UpdateRemainTimeFraction(float fraction,int remainTime)197 void RSAnimationFraction::UpdateRemainTimeFraction(float fraction, int remainTime)
198 {
199     int64_t remainTimeNS = remainTime * MS_TO_NS;
200     int64_t durationNs = duration_ * MS_TO_NS;
201     int64_t startDelayNs = startDelay_ * MS_TO_NS;
202     float curRemainProgress = currentIsReverseCycle_ ? curTimeFraction_ : (1.0f - curTimeFraction_);
203     float ratio = 1.0f;
204     if (remainTime != 0) {
205         ratio = curRemainProgress * durationNs / remainTimeNS;
206     }
207 
208     if (runningTime_ > startDelayNs || fabs(fraction) > 1e-6) {
209         if (currentIsReverseCycle_) {
210             runningTime_ =
211                 static_cast<int64_t>(durationNs * (1.0f - fraction)) + startDelayNs + curRepeatCount_ * durationNs;
212         } else {
213             runningTime_ = static_cast<int64_t>(durationNs * fraction) + startDelayNs + curRepeatCount_ * durationNs;
214         }
215     }
216 
217     speed_ = speed_ * ratio;
218     curTimeFraction_ = fraction;
219 }
220 } // namespace Rosen
221 } // namespace OHOS
222