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_interpolator.h"
17
18 #include <algorithm>
19 #include <cmath>
20
21 #include "animation/rs_animation_common.h"
22 #include "animation/rs_cubic_bezier_interpolator.h"
23 #include "animation/rs_spring_interpolator.h"
24 #include "animation/rs_steps_interpolator.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 const std::shared_ptr<RSInterpolator> RSInterpolator::DEFAULT =
29 std::make_shared<RSCubicBezierInterpolator>(0.42f, 0.0f, 0.58f, 1.0f);
30
Unmarshalling(Parcel & parcel)31 RSInterpolator* RSInterpolator::Unmarshalling(Parcel& parcel)
32 {
33 uint16_t interpolatorType = parcel.ReadUint16();
34 RSInterpolator* ret = nullptr;
35 switch (interpolatorType) {
36 case InterpolatorType::LINEAR:
37 ret = new LinearInterpolator();
38 break;
39 case InterpolatorType::CUSTOM:
40 ret = RSCustomInterpolator::Unmarshalling(parcel);
41 break;
42 case InterpolatorType::CUBIC_BEZIER:
43 ret = RSCubicBezierInterpolator::Unmarshalling(parcel);
44 break;
45 case InterpolatorType::SPRING:
46 ret = RSSpringInterpolator::Unmarshalling(parcel);
47 break;
48 case InterpolatorType::STEPS:
49 ret = RSStepsInterpolator::Unmarshalling(parcel);
50 break;
51 default:
52 break;
53 }
54 return ret;
55 }
56
Unmarshalling(Parcel & parcel)57 RSCustomInterpolator* RSCustomInterpolator::Unmarshalling(Parcel& parcel)
58 {
59 std::vector<float> times, values;
60 if (!(parcel.ReadFloatVector(×) && parcel.ReadFloatVector(&values))) {
61 ROSEN_LOGE("Unmarshalling CustomInterpolator failed");
62 return nullptr;
63 }
64 return new RSCustomInterpolator(std::move(times), std::move(values));
65 }
66
RSCustomInterpolator(const std::vector<float> && times,const std::vector<float> && values)67 RSCustomInterpolator::RSCustomInterpolator(const std::vector<float>&& times, const std::vector<float>&& values)
68 : times_(times), values_(values)
69 {}
70
RSCustomInterpolator(const std::function<float (float)> & func,int duration)71 RSCustomInterpolator::RSCustomInterpolator(const std::function<float(float)>& func, int duration)
72 : interpolateFunc_(func)
73 {
74 Convert(duration);
75 }
76
Convert(int duration)77 void RSCustomInterpolator::Convert(int duration)
78 {
79 if (interpolateFunc_ == nullptr) {
80 ROSEN_LOGE("RSCustomInterpolator::Convert, interpolateFunc_ is nullptr");
81 return;
82 }
83 uint64_t frameInterval = 16666667;
84 int numAnim = static_cast<int>(std::ceil(static_cast<double>(duration * MS_TO_NS) / frameInterval));
85 const int maxSamplePoints = 300;
86 const int minSamplePoints = 2;
87 numAnim = std::min(std::max(minSamplePoints, numAnim), maxSamplePoints);
88 float lastAnimFrame = numAnim - 1;
89 for (int i = 0; i < numAnim; i++) {
90 float time = i / lastAnimFrame;
91 float value = interpolateFunc_(time);
92 times_.push_back(time);
93 values_.push_back(value);
94 }
95 }
96
Interpolate(float input) const97 float RSCustomInterpolator::Interpolate(float input) const
98 {
99 if (input < times_[0] + EPSILON) {
100 return times_[0];
101 }
102 if (input > times_[times_.size() - 1] - EPSILON) {
103 return times_[times_.size() - 1];
104 }
105 auto firstGreatValue = upper_bound(times_.begin(), times_.end(), input);
106 int endLocation = firstGreatValue - times_.begin();
107 int startLocation = endLocation - 1;
108
109 float fraction = (input - times_[startLocation]) / (times_[endLocation] - times_[startLocation]);
110 float ret = fraction * (values_[endLocation] - values_[startLocation]) + values_[startLocation];
111 return ret;
112 }
113 } // namespace Rosen
114 } // namespace OHOS
115