• 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_interpolator.h"
17 
18 #include <algorithm>
19 #include <cmath>
20 
21 #include "sandbox_utils.h"
22 
23 #include "animation/rs_animation_common.h"
24 #include "animation/rs_cubic_bezier_interpolator.h"
25 #include "animation/rs_spring_interpolator.h"
26 #include "animation/rs_steps_interpolator.h"
27 #include "platform/common/rs_log.h"
28 #include "transaction/rs_marshalling_helper.h"
29 
30 namespace OHOS {
31 namespace Rosen {
32 
33 static pid_t pid_ = GetRealPid();
34 
35 const std::shared_ptr<RSInterpolator> RSInterpolator::DEFAULT =
36     std::make_shared<RSCubicBezierInterpolator>(0.42f, 0.0f, 0.58f, 1.0f);
37 
RSInterpolator()38 RSInterpolator::RSInterpolator() : id_(GenerateId()) {}
39 
Init()40 void RSInterpolator::Init()
41 {
42     pid_ = GetRealPid();
43 }
44 
GenerateId()45 uint64_t RSInterpolator::GenerateId()
46 {
47     if (pid_ == 0) {
48         pid_ = GetRealPid();
49     }
50     static std::atomic<uint32_t> currentId_ = 0;
51 
52     auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
53     if (currentId == UINT32_MAX) {
54         ROSEN_LOGE("RSInterpolator Id overflow");
55     }
56 
57     // concat two 32-bit numbers to one 64-bit number
58     return ((AnimationId)pid_ << 32) | (currentId);
59 }
60 
Interpolate(float input)61 float RSInterpolator::Interpolate(float input)
62 {
63     if (input == prevInput_) {
64         return prevOutput_;
65     }
66     prevInput_ = input;
67     prevOutput_ = InterpolateImpl(input);
68     return prevOutput_;
69 }
70 
RSCustomInterpolator(uint64_t id,const std::vector<float> && times,const std::vector<float> && values)71 RSCustomInterpolator::RSCustomInterpolator(
72     uint64_t id, const std::vector<float>&& times, const std::vector<float>&& values)
73     : RSInterpolator(id), times_(times), values_(values)
74 {}
75 
RSCustomInterpolator(const std::function<float (float)> & func,int duration)76 RSCustomInterpolator::RSCustomInterpolator(const std::function<float(float)>& func, int duration)
77     : interpolateFunc_(func)
78 {
79     Convert(duration);
80 }
81 
Convert(int duration)82 void RSCustomInterpolator::Convert(int duration)
83 {
84     if (interpolateFunc_ == nullptr) {
85         ROSEN_LOGE("RSCustomInterpolator::Convert, interpolateFunc_ is nullptr");
86         return;
87     }
88     constexpr uint64_t frameInterval = 16666667;
89     int numAnim = static_cast<int>(std::ceil(static_cast<double>(duration * MS_TO_NS) / frameInterval));
90     numAnim = std::clamp(numAnim, MIN_SAMPLE_POINTS, MAX_SAMPLE_POINTS);
91     float lastAnimFrame = numAnim - 1;
92     if (lastAnimFrame <= 0.0f) {
93         ROSEN_LOGE("RSCustomInterpolator::Convert, lastAnimFrame is invalid.");
94         return;
95     }
96     for (int i = 0; i < numAnim; i++) {
97         float time = i / lastAnimFrame;
98         float value = interpolateFunc_(time);
99         times_.push_back(time);
100         values_.push_back(value);
101     }
102 }
103 
InterpolateImpl(float input) const104 float RSCustomInterpolator::InterpolateImpl(float input) const
105 {
106     if (times_.size() <= 0) {
107         ROSEN_LOGE("RSCustomInterpolator::InterpolateImpl, times_ vector is empty.");
108         return 0.0f;
109     }
110     if (times_.size() != values_.size()) {
111         ROSEN_LOGE("RSCustomInterpolator::InterpolateImpl, times_ and values_ have different sizes.");
112         return 0.0f;
113     }
114     auto firstGreatValueIterator = std::upper_bound(times_.begin(), times_.end(), input);
115     if (firstGreatValueIterator == times_.end()) {
116         return values_.back();
117     }
118     if (firstGreatValueIterator == times_.begin()) {
119         return values_.front();
120     }
121     auto endLocation = std::distance(times_.begin(), firstGreatValueIterator);
122     int startLocation = endLocation - 1;
123     float number = times_[endLocation] - times_[startLocation];
124     if (ROSEN_LE(number, 0.f)) {
125         ROSEN_LOGE("RSCustomInterpolator::Interpolate, time between startLocation and endLocation is less than zero.");
126         return 0.0f;
127     }
128     float fraction = (input - times_[startLocation]) / number;
129     float ret = fraction * (values_[endLocation] - values_[startLocation]) + values_[startLocation];
130     return ret;
131 }
132 } // namespace Rosen
133 } // namespace OHOS
134