• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_render_spring_animation.h"
17 
18 #include "pipeline/rs_render_node.h"
19 #include "platform/common/rs_log.h"
20 
21 namespace OHOS {
22 namespace Rosen {
RSRenderSpringAnimation(AnimationId id,const PropertyId & propertyId,const std::shared_ptr<RSRenderPropertyBase> & originValue,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue)23 RSRenderSpringAnimation::RSRenderSpringAnimation(AnimationId id, const PropertyId& propertyId,
24     const std::shared_ptr<RSRenderPropertyBase>& originValue,
25     const std::shared_ptr<RSRenderPropertyBase>& startValue,
26     const std::shared_ptr<RSRenderPropertyBase>& endValue)
27     : RSRenderPropertyAnimation(id, propertyId, originValue),
28     RSSpringModel<std::shared_ptr<RSRenderPropertyBase>>(),
29     startValue_(startValue), endValue_(endValue)
30 {
31     // spring model is not initialized, so we can't calculate estimated duration
32 }
33 
SetSpringParameters(float response,float dampingRatio)34 void RSRenderSpringAnimation::SetSpringParameters(float response, float dampingRatio)
35 {
36     response_ = response;
37     dampingRatio_ = dampingRatio;
38 }
39 
40 #ifdef ROSEN_OHOS
Marshalling(Parcel & parcel) const41 bool RSRenderSpringAnimation::Marshalling(Parcel& parcel) const
42 {
43     if (!RSRenderPropertyAnimation::Marshalling(parcel)) {
44         ROSEN_LOGE("RSRenderSpringAnimation::Marshalling, RenderPropertyAnimation failed");
45         return false;
46     }
47     if (!(RSRenderPropertyBase::Marshalling(parcel, startValue_) &&
48             RSRenderPropertyBase::Marshalling(parcel, endValue_))) {
49         ROSEN_LOGE("RSRenderSpringAnimation::Marshalling, MarshallingHelper failed");
50         return false;
51     }
52 
53     if (!(RSMarshallingHelper::Marshalling(parcel, response_) &&
54             RSMarshallingHelper::Marshalling(parcel, dampingRatio_))) {
55         return false;
56     }
57 
58     return true;
59 }
60 
Unmarshalling(Parcel & parcel)61 RSRenderSpringAnimation* RSRenderSpringAnimation::Unmarshalling(Parcel& parcel)
62 {
63     auto* renderSpringAnimation = new RSRenderSpringAnimation();
64     if (!renderSpringAnimation->ParseParam(parcel)) {
65         ROSEN_LOGE("RSRenderSpringAnimation::Unmarshalling, failed");
66         delete renderSpringAnimation;
67         return nullptr;
68     }
69     return renderSpringAnimation;
70 }
71 
ParseParam(Parcel & parcel)72 bool RSRenderSpringAnimation::ParseParam(Parcel& parcel)
73 {
74     if (!RSRenderPropertyAnimation::ParseParam(parcel)) {
75         ROSEN_LOGE("RSRenderSpringAnimation::ParseParam, ParseParam Fail");
76         return false;
77     }
78 
79     if (!(RSRenderPropertyBase::Unmarshalling(parcel, startValue_) &&
80             RSRenderPropertyBase::Unmarshalling(parcel, endValue_))) {
81         return false;
82     }
83 
84     if (!(RSMarshallingHelper::Unmarshalling(parcel, response_) &&
85             RSMarshallingHelper::Unmarshalling(parcel, dampingRatio_))) {
86         return false;
87     }
88 
89     return true;
90 }
91 #endif
92 
OnSetFraction(float fraction)93 void RSRenderSpringAnimation::OnSetFraction(float fraction)
94 {
95     // spring animation should not support set fraction
96     OnAnimate(fraction);
97 }
98 
OnAnimate(float fraction)99 void RSRenderSpringAnimation::OnAnimate(float fraction)
100 {
101     if (GetPropertyId() == 0) {
102         return;
103     } else if (ROSEN_EQ(fraction, 1.0f)) {
104         SetAnimationValue(endValue_);
105         prevMappedTime_ = GetDuration() * MILLISECOND_TO_SECOND;
106         return;
107     }
108     auto mappedTime = fraction * GetDuration() * MILLISECOND_TO_SECOND;
109     auto displacement = CalculateDisplacement(mappedTime);
110     SetAnimationValue(endValue_ + displacement);
111 
112     // keep the mapped time, this will be used to calculate instantaneous velocity
113     prevMappedTime_ = mappedTime;
114 }
115 
OnAttach()116 void RSRenderSpringAnimation::OnAttach()
117 {
118     auto target = GetTarget();
119     if (target == nullptr) {
120         ROSEN_LOGE("RSRenderSpringAnimation::OnAttach, target is nullptr");
121         return;
122     }
123     // check if any other spring animation running on this property
124     auto propertyId = GetPropertyId();
125     auto prevAnimation = target->GetAnimationManager().QuerySpringAnimation(propertyId);
126     target->GetAnimationManager().RegisterSpringAnimation(propertyId, GetAnimationId());
127 
128     // return if no other spring animation(s) running, or the other animation is finished
129     // meanwhile, align run time for both spring animations, prepare for status inheritance
130     if (prevAnimation == nullptr || prevAnimation->Animate(animationFraction_.GetLastFrameTime())) {
131         return;
132     }
133 
134     // extract spring status from previous spring animation
135     auto prevSpringAnimation = std::static_pointer_cast<RSRenderSpringAnimation>(prevAnimation);
136     auto status = prevSpringAnimation->GetSpringStatus();
137 
138     // inherit spring status from previous spring animation
139     startValue_ = std::get<0>(status);
140     originValue_ = startValue_->Clone();
141     lastValue_ = startValue_->Clone();
142     initialVelocity_ = std::get<1>(status);
143 
144     // set previous spring animation to FINISHED
145     prevSpringAnimation->FinishOnCurrentPosition();
146 }
147 
OnDetach()148 void RSRenderSpringAnimation::OnDetach()
149 {
150     auto target = GetTarget();
151     if (target == nullptr) {
152         ROSEN_LOGE("RSRenderSpringAnimation::OnDetach, target is nullptr");
153         return;
154     }
155     auto propertyId = GetPropertyId();
156     auto id = GetAnimationId();
157     target->GetAnimationManager().UnregisterSpringAnimation(propertyId, id);
158 }
159 
OnInitialize()160 void RSRenderSpringAnimation::OnInitialize()
161 {
162     // set the initial status of spring model
163     initialOffset_ = startValue_ - endValue_;
164     if (initialVelocity_ == nullptr) {
165         initialVelocity_ = initialOffset_ * 0.f;
166     }
167     CalculateSpringParameters();
168     // use duration calculated by spring model as animation duration
169     SetDuration(std::lroundf(GetEstimatedDuration() * SECOND_TO_MILLISECOND));
170 }
171 
172 std::tuple<std::shared_ptr<RSRenderPropertyBase>, std::shared_ptr<RSRenderPropertyBase>>
GetSpringStatus()173 RSRenderSpringAnimation::GetSpringStatus()
174 {
175     // if animation is never started, return start value and initial velocity
176     if (ROSEN_EQ(prevMappedTime_, 0.0f)) {
177         return { startValue_, initialVelocity_ };
178     }
179 
180     auto displacement = lastValue_ - endValue_;
181 
182     // use average velocity over a small time interval to estimate instantaneous velocity
183     constexpr double TIME_INTERVAL = 1e-6f; // 1e-6f : 1 microsecond to seconds
184     auto velocity = (CalculateDisplacement(prevMappedTime_ + TIME_INTERVAL) - displacement) * (1 / TIME_INTERVAL);
185 
186     // return current position and velocity
187     return { lastValue_->Clone(), velocity };
188 }
189 } // namespace Rosen
190 } // namespace OHOS
191