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 #ifndef RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_VALUE_ESTIMATOR_H
17 #define RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_VALUE_ESTIMATOR_H
18 
19 #include <memory>
20 
21 #include "rs_spring_model.h"
22 
23 #include "animation/rs_animation_common.h"
24 #include "animation/rs_interpolator.h"
25 #include "common/rs_color.h"
26 #include "common/rs_macros.h"
27 #include "common/rs_matrix3.h"
28 #include "common/rs_vector2.h"
29 #include "common/rs_vector4.h"
30 #include "modifier/rs_modifier_type.h"
31 #include "render/rs_filter.h"
32 
33 namespace OHOS {
34 namespace Rosen {
35 class RSRenderPropertyBase;
36 template<typename T>
37 class RSRenderAnimatableProperty;
38 
39 class RSB_EXPORT RSValueEstimator {
40 public:
41     template<typename T>
Estimate(float fraction,const T & startValue,const T & endValue)42     T Estimate(float fraction, const T& startValue, const T& endValue)
43     {
44         return startValue * (1.0f - fraction) + endValue * fraction;
45     }
46 
47     Quaternion Estimate(float fraction, const Quaternion& startValue, const Quaternion& endValue);
48 
49     std::shared_ptr<RSFilter> Estimate(
50         float fraction, const std::shared_ptr<RSFilter>& startValue, const std::shared_ptr<RSFilter>& endValue);
51 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator)52     virtual float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator)
53     {
54         return 0.0f;
55     }
56 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator,float targetFraction,int duration)57     virtual float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator,
58         float targetFraction, int duration)
59     {
60         return 0.0f;
61     }
62 
InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)63     virtual void InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
64         const std::shared_ptr<RSRenderPropertyBase>& startValue,
65         const std::shared_ptr<RSRenderPropertyBase>& endValue,
66         const std::shared_ptr<RSRenderPropertyBase>& lastValue) {}
67 
InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)68     virtual void InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
69         std::vector<std::tuple<float, std::shared_ptr<RSRenderPropertyBase>,
70         std::shared_ptr<RSInterpolator>>>& keyframes,
71         const std::shared_ptr<RSRenderPropertyBase>& lastValue) {}
72 
InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)73     virtual void InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
74         std::vector<std::tuple<float, float, std::shared_ptr<RSRenderPropertyBase>,
75         std::shared_ptr<RSInterpolator>>>& keyframes,
76         const std::shared_ptr<RSRenderPropertyBase>& lastValue) {}
77 
78     virtual void UpdateAnimationValue(const float fraction, const bool isAdditive) = 0;
79 };
80 
81 template<typename T>
82 class RSB_EXPORT_TMP RSCurveValueEstimator : public RSValueEstimator {
83 public:
84     RSCurveValueEstimator() = default;
85     virtual ~RSCurveValueEstimator() = default;
86 
InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)87     void InitCurveAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
88         const std::shared_ptr<RSRenderPropertyBase>& startValue,
89         const std::shared_ptr<RSRenderPropertyBase>& endValue,
90         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
91     {
92         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
93         auto animatableStartValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(startValue);
94         auto animatableEndValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(endValue);
95         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
96         if (animatableProperty && animatableStartValue && animatableEndValue && animatableLastValue) {
97             property_ = animatableProperty;
98             startValue_ = animatableStartValue->Get();
99             endValue_ = animatableEndValue->Get();
100             lastValue_ = animatableLastValue->Get();
101         }
102     }
103 
UpdateAnimationValue(const float fraction,const bool isAdditive)104     void UpdateAnimationValue(const float fraction, const bool isAdditive) override
105     {
106         auto animationValue = GetAnimationValue(fraction, isAdditive);
107         if (property_ != nullptr) {
108             property_->Set(animationValue);
109         }
110     }
111 
GetAnimationValue(const float fraction,const bool isAdditive)112     T GetAnimationValue(const float fraction, const bool isAdditive)
113     {
114         auto interpolationValue = RSValueEstimator::Estimate(fraction, startValue_, endValue_);
115         auto animationValue = interpolationValue;
116         if (isAdditive && property_ != nullptr) {
117             animationValue = property_->Get() + (interpolationValue - lastValue_);
118         }
119         lastValue_ = interpolationValue;
120         return animationValue;
121     }
122 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator)123     float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator) override
124     {
125         return 0.0f;
126     }
127 
EstimateFraction(const std::shared_ptr<RSInterpolator> & interpolator,float targetFraction,int duration)128     float EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator,
129         float targetFraction, int duration) override
130     {
131         if (interpolator == nullptr || duration <= 0) {
132             return FRACTION_MIN;
133         }
134         int secondTime = std::ceil(static_cast<float>(duration) / SECOND_TO_MS);
135         if (secondTime <= 0) {
136             return FRACTION_MIN;
137         }
138         auto frameTimes = MAX_FRAME_TIME_FRACTION * secondTime;
139         float lastFraction = FRACTION_MIN;
140         for (int time = 1; time <= frameTimes; time++) {
141             float frameFraction = static_cast<float>(time) / frameTimes;
142             frameFraction = std::clamp(frameFraction, 0.0f, 1.0f);
143             float fraction = interpolator->Interpolate(frameFraction);
144             if (lastFraction <= targetFraction && fraction >= targetFraction) {
145                 return frameFraction;
146             }
147             lastFraction = fraction;
148         }
149         return FRACTION_MIN;
150     }
151 private:
152     T startValue_ {};
153     T endValue_ {};
154     T lastValue_ {};
155     std::shared_ptr<RSRenderAnimatableProperty<T>> property_;
156 };
157 
158 template<>
159 float RSCurveValueEstimator<float>::EstimateFraction(const std::shared_ptr<RSInterpolator>& interpolator);
160 
161 extern template class RSCurveValueEstimator<float>;
162 
163 template<typename T>
164 class RSKeyframeValueEstimator : public RSValueEstimator {
165 public:
166     RSKeyframeValueEstimator() = default;
167     virtual ~RSKeyframeValueEstimator() = default;
168 
InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)169     void InitKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
170         std::vector<std::tuple<float, std::shared_ptr<RSRenderPropertyBase>,
171         std::shared_ptr<RSInterpolator>>>& keyframes,
172         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
173     {
174         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
175         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
176         if (animatableProperty && animatableLastValue) {
177             property_ = animatableProperty;
178             lastValue_ = animatableLastValue->Get();
179         }
180         for (const auto& keyframe : keyframes) {
181             auto keyframeValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(std::get<1>(keyframe));
182             if (keyframeValue != nullptr) {
183                 keyframes_.push_back({ std::get<0>(keyframe), keyframeValue->Get(), std::get<2>(keyframe) });
184             }
185         }
186     }
187 
InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & property,std::vector<std::tuple<float,float,std::shared_ptr<RSRenderPropertyBase>,std::shared_ptr<RSInterpolator>>> & keyframes,const std::shared_ptr<RSRenderPropertyBase> & lastValue)188     void InitDurationKeyframeAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& property,
189         std::vector<std::tuple<float, float, std::shared_ptr<RSRenderPropertyBase>,
190         std::shared_ptr<RSInterpolator>>>& keyframes,
191         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
192     {
193         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
194         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
195         if (animatableProperty && animatableLastValue) {
196             property_ = animatableProperty;
197             lastValue_ = animatableLastValue->Get();
198         }
199         for (const auto& keyframe : keyframes) {
200             auto keyframeValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(std::get<2>(keyframe));
201             if (keyframeValue != nullptr) {
202                 durationKeyframes_.push_back(
203                     { std::get<0>(keyframe), std::get<1>(keyframe), keyframeValue->Get(), std::get<3>(keyframe) });
204             }
205         }
206     }
207 
UpdateAnimationValue(const float fraction,const bool isAdditive)208     void UpdateAnimationValue(const float fraction, const bool isAdditive) override
209     {
210         auto animationValue = GetAnimationValue(fraction, isAdditive);
211         if (property_ != nullptr) {
212             property_->Set(animationValue);
213         }
214     }
215 
GetAnimationValue(const float fraction,const bool isAdditive)216     T GetAnimationValue(const float fraction, const bool isAdditive)
217     {
218         if (!(durationKeyframes_.empty())) {
219             return GetDurationKeyframeAnimationValue(fraction, isAdditive);
220         }
221         float preKeyframeFraction = std::get<0>(keyframes_.front());
222         auto preKeyframeValue = std::get<1>(keyframes_.front());
223         for (const auto& keyframe : keyframes_) {
224             // the index of tuple
225             float keyframeFraction = std::get<0>(keyframe);
226             auto keyframeValue = std::get<1>(keyframe);
227             auto keyframeInterpolator = std::get<2>(keyframe);
228             if (fraction <= keyframeFraction) {
229                 if (ROSEN_EQ(keyframeFraction, preKeyframeFraction)) {
230                     continue;
231                 }
232 
233                 float intervalFraction = (fraction - preKeyframeFraction) / (keyframeFraction - preKeyframeFraction);
234                 auto interpolationValue = RSValueEstimator::Estimate(
235                     keyframeInterpolator->Interpolate(intervalFraction), preKeyframeValue, keyframeValue);
236                 auto animationValue = interpolationValue;
237                 if (isAdditive && property_ != nullptr) {
238                     animationValue = property_->Get() + (interpolationValue - lastValue_);
239                 }
240                 lastValue_ = interpolationValue;
241                 return animationValue;
242             }
243 
244             preKeyframeFraction = keyframeFraction;
245             preKeyframeValue = keyframeValue;
246         }
247         return preKeyframeValue;
248     }
249 
GetDurationKeyframeAnimationValue(const float fraction,const bool isAdditive)250     T GetDurationKeyframeAnimationValue(const float fraction, const bool isAdditive)
251     {
252         auto preKeyframeValue = std::get<2>(durationKeyframes_.front());
253         auto animationValue = preKeyframeValue;
254         bool bInFraction = false;
255         for (const auto& keyframe : durationKeyframes_) {
256             float startFraction = std::get<0>(keyframe);
257             float endFraction = std::get<1>(keyframe);
258             auto keyframeValue = std::get<2>(keyframe);
259             auto keyframeInterpolator = std::get<3>(keyframe);
260             if (fraction < startFraction) {
261                 break;
262             }
263             if ((fraction > startFraction) && (fraction <= endFraction)) {
264                 bInFraction = true;
265                 float intervalFraction = (fraction - startFraction) / (endFraction - startFraction);
266                 auto interpolationValue = RSValueEstimator::Estimate(
267                     keyframeInterpolator->Interpolate(intervalFraction), preKeyframeValue, keyframeValue);
268                 animationValue = interpolationValue;
269                 if (isAdditive && property_ != nullptr) {
270                     animationValue = property_->Get() + (interpolationValue - lastValue_);
271                 }
272                 lastValue_ = interpolationValue;
273                 preKeyframeValue = animationValue;
274                 continue;
275             }
276             if (fraction == startFraction && startFraction == endFraction) {
277                 bInFraction = true;
278                 animationValue = keyframeValue;
279                 preKeyframeValue = keyframeValue;
280                 lastValue_ = keyframeValue;
281                 continue;
282             }
283             preKeyframeValue = keyframeValue;
284         }
285         if (!bInFraction) {
286             animationValue = preKeyframeValue;
287             lastValue_ = preKeyframeValue;
288         }
289         return animationValue;
290     }
291 
292 private:
293     std::vector<std::tuple<float, T, std::shared_ptr<RSInterpolator>>> keyframes_;
294     std::vector<std::tuple<float, float, T, std::shared_ptr<RSInterpolator>>> durationKeyframes_;
295     T lastValue_ {};
296     std::shared_ptr<RSRenderAnimatableProperty<T>> property_;
297 };
298 
299 enum class RSValueEstimatorType : int16_t {
300     INVALID = 0,
301     CURVE_VALUE_ESTIMATOR,
302     KEYFRAME_VALUE_ESTIMATOR,
303     PATH_VALUE_ESTIMATOR,
304 };
305 
306 class RSB_EXPORT RSSpringValueEstimatorBase {
307 public:
308     RSSpringValueEstimatorBase() = default;
309     virtual ~RSSpringValueEstimatorBase() = default;
310 
SetResponse(const float response)311     virtual void SetResponse(const float response) {}
SetDampingRatio(const float dampingRatio)312     virtual void SetDampingRatio(const float dampingRatio) {}
GetResponse()313     virtual float GetResponse() const
314     {
315         return 0.0f;
316     }
GetDampingRatio()317     virtual float GetDampingRatio() const
318     {
319         return 0.0f;
320     }
SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase> & initialVelocity)321     virtual void SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase>& initialVelocity) {}
InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)322     virtual void InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase>& property,
323         const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& endValue,
324         const std::shared_ptr<RSRenderPropertyBase>& lastValue)
325     {}
UpdateStartValueAndLastValue(const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)326     virtual void UpdateStartValueAndLastValue(
327         const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& lastValue)
328     {}
UpdateAnimationValue(const float time,const bool isAdditive)329     virtual void UpdateAnimationValue(const float time, const bool isAdditive) {}
GetAnimationProperty()330     virtual std::shared_ptr<RSRenderPropertyBase> GetAnimationProperty() const
331     {
332         return nullptr;
333     }
GetPropertyVelocity(float time)334     virtual std::shared_ptr<RSRenderPropertyBase> GetPropertyVelocity(float time) const
335     {
336         return nullptr;
337     }
UpdateDuration()338     virtual float UpdateDuration()
339     {
340         return 0.0f;
341     }
UpdateSpringParameters()342     virtual void UpdateSpringParameters() {}
343 };
344 
345 template<typename T>
346 class RSSpringValueEstimator : public RSSpringValueEstimatorBase {
347 public:
RSSpringValueEstimator()348     RSSpringValueEstimator() : RSSpringValueEstimatorBase()
349     {
350         InitSpringModel();
351     }
352 
353     ~RSSpringValueEstimator() override = default;
354 
InitSpringModel()355     void InitSpringModel()
356     {
357         if (!springModel_) {
358             springModel_ = std::make_shared<RSSpringModel<T>>();
359         }
360     }
361 
SetResponse(const float response)362     void SetResponse(const float response) override
363     {
364         if (springModel_) {
365             springModel_->response_ = response;
366         }
367     }
368 
SetDampingRatio(const float dampingRatio)369     void SetDampingRatio(const float dampingRatio) override
370     {
371         if (springModel_) {
372             springModel_->dampingRatio_ = dampingRatio;
373         }
374     }
375 
GetResponse()376     float GetResponse() const override
377     {
378         if (springModel_) {
379             return springModel_->response_;
380         }
381         return 0.0f;
382     }
383 
GetDampingRatio()384     float GetDampingRatio() const override
385     {
386         if (springModel_) {
387             return springModel_->dampingRatio_;
388         }
389         return 0.0f;
390     }
391 
SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase> & initialVelocity)392     void SetInitialVelocity(const std::shared_ptr<RSRenderPropertyBase>& initialVelocity) override
393     {
394         auto animatableInitialVelocity = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(initialVelocity);
395         if (animatableInitialVelocity != nullptr && springModel_ != nullptr) {
396             springModel_->initialVelocity_ = animatableInitialVelocity->Get();
397         }
398     }
399 
InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase> & property,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)400     void InitRSSpringValueEstimator(const std::shared_ptr<RSRenderPropertyBase>& property,
401         const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& endValue,
402         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
403     {
404         auto animatableProperty = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(property);
405         auto animatableStartValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(startValue);
406         auto animatableEndValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(endValue);
407         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
408         if (animatableProperty && animatableStartValue && animatableEndValue && animatableLastValue) {
409             property_ = animatableProperty;
410             startValue_ = animatableStartValue->Get();
411             endValue_ = animatableEndValue->Get();
412             lastValue_ = animatableLastValue->Get();
413             if (springModel_) {
414                 springModel_->initialOffset_ = startValue_ - endValue_;
415             }
416         }
417     }
418 
UpdateStartValueAndLastValue(const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & lastValue)419     void UpdateStartValueAndLastValue(const std::shared_ptr<RSRenderPropertyBase>& startValue,
420         const std::shared_ptr<RSRenderPropertyBase>& lastValue) override
421     {
422         auto animatableStartValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(startValue);
423         auto animatableLastValue = std::static_pointer_cast<RSRenderAnimatableProperty<T>>(lastValue);
424         if (animatableStartValue && animatableLastValue) {
425             startValue_ = animatableStartValue->Get();
426             lastValue_ = animatableLastValue->Get();
427             if (springModel_) {
428                 springModel_->initialOffset_ = startValue_ - endValue_;
429             }
430         }
431     }
432 
UpdateAnimationValue(const float time,const bool isAdditive)433     void UpdateAnimationValue(const float time, const bool isAdditive) override
434     {
435         auto animationValue = GetAnimationValue(time, isAdditive);
436         if (property_ != nullptr) {
437             property_->Set(animationValue);
438         }
439     }
440 
GetAnimationValue(const float time,const bool isAdditive)441     T GetAnimationValue(const float time, const bool isAdditive)
442     {
443         T currentValue = startValue_;
444         constexpr static float TIME_THRESHOLD = 1e-3f;
445         if (ROSEN_EQ(time, duration_, TIME_THRESHOLD)) {
446             currentValue = endValue_;
447         } else if (springModel_) {
448             currentValue = springModel_->CalculateDisplacement(time) + endValue_;
449         }
450 
451         auto animationValue = currentValue;
452         if (isAdditive && property_) {
453             animationValue = property_->Get() + currentValue - lastValue_;
454         }
455         lastValue_ = currentValue;
456         return animationValue;
457     }
458 
GetAnimationProperty()459     std::shared_ptr<RSRenderPropertyBase> GetAnimationProperty() const override
460     {
461         return std::make_shared<RSRenderAnimatableProperty<T>>(lastValue_);
462     }
463 
GetPropertyVelocity(float time)464     std::shared_ptr<RSRenderPropertyBase> GetPropertyVelocity(float time) const override
465     {
466         if (!springModel_) {
467             return nullptr;
468         }
469         constexpr float TIME_INTERVAL = 1e-6f; // 1 microsecond
470         T velocity = (springModel_->CalculateDisplacement(time + TIME_INTERVAL) -
471             springModel_->CalculateDisplacement(time)) * (1 / TIME_INTERVAL);
472         return std::make_shared<RSRenderAnimatableProperty<T>>(velocity);
473     }
474 
UpdateDuration()475     float UpdateDuration() override
476     {
477         if (springModel_) {
478             duration_ = springModel_->EstimateDuration();
479         }
480         return duration_;
481     }
482 
UpdateSpringParameters()483     void UpdateSpringParameters() override
484     {
485         if (springModel_) {
486             springModel_->CalculateSpringParameters();
487         }
488     }
489 
490 private:
491     T startValue_ {};
492     T endValue_ {};
493     T lastValue_ {};
494     float duration_ = 0.3f;
495     std::shared_ptr<RSSpringModel<T>> springModel_;
496     std::shared_ptr<RSRenderAnimatableProperty<T>> property_;
497 };
498 } // namespace Rosen
499 } // namespace OHOS
500 
501 #endif // RENDER_SERVICE_CLIENT_CORE_ANIMATION_RS_VALUE_ESTIMATOR_H
502