1 /*
2  * Copyright (c) 2022-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_render_property_animation.h"
17 
18 #include "animation/rs_animation_trace_utils.h"
19 #include "modifier/rs_render_property.h"
20 #include "platform/common/rs_log.h"
21 #include "transaction/rs_marshalling_helper.h"
22 #include "rs_profiler.h"
23 
24 namespace OHOS {
25 namespace Rosen {
RSRenderPropertyAnimation(AnimationId id,const PropertyId & propertyId,const std::shared_ptr<RSRenderPropertyBase> & originValue)26 RSRenderPropertyAnimation::RSRenderPropertyAnimation(AnimationId id, const PropertyId& propertyId,
27     const std::shared_ptr<RSRenderPropertyBase>& originValue) : RSRenderAnimation(id), propertyId_(propertyId),
28     originValue_(originValue->Clone()), lastValue_(originValue->Clone())
29 {}
30 
DumpAnimationType(std::string & out) const31 void RSRenderPropertyAnimation::DumpAnimationType(std::string& out) const
32 {
33     out += "Type:RSRenderPropertyAnimation";
34 }
35 
GetPropertyId() const36 PropertyId RSRenderPropertyAnimation::GetPropertyId() const
37 {
38     return propertyId_;
39 }
40 
SetAdditive(bool isAdditive)41 void RSRenderPropertyAnimation::SetAdditive(bool isAdditive)
42 {
43     if (IsStarted()) {
44         ROSEN_LOGE("Failed to set additive, animation has started!");
45         return;
46     }
47 
48     isAdditive_ = isAdditive;
49 }
50 
GetAdditive()51 bool RSRenderPropertyAnimation::GetAdditive()
52 {
53     return isAdditive_;
54 }
55 
AttachRenderProperty(const std::shared_ptr<RSRenderPropertyBase> & property)56 void RSRenderPropertyAnimation::AttachRenderProperty(const std::shared_ptr<RSRenderPropertyBase>& property)
57 {
58     property_ = property;
59     if (property_ == nullptr) {
60         return;
61     }
62     InitValueEstimator();
63     if (originValue_ != nullptr) {
64         property_->SetPropertyType(originValue_->GetPropertyType());
65     }
66 }
67 
Marshalling(Parcel & parcel) const68 bool RSRenderPropertyAnimation::Marshalling(Parcel& parcel) const
69 {
70     if (!RSRenderAnimation::Marshalling(parcel)) {
71         ROSEN_LOGE("RSRenderPropertyAnimation::Marshalling, RenderAnimation failed");
72         return false;
73     }
74     if (!parcel.WriteUint64(propertyId_)) {
75         ROSEN_LOGE("RSRenderPropertyAnimation::Marshalling, write PropertyId failed");
76         return false;
77     }
78     if (!(RSMarshallingHelper::Marshalling(parcel, isAdditive_) &&
79             RSRenderPropertyBase::Marshalling(parcel, originValue_))) {
80         ROSEN_LOGE("RSRenderPropertyAnimation::Marshalling, write value failed");
81         return false;
82     }
83     return true;
84 }
85 
ParseParam(Parcel & parcel)86 bool RSRenderPropertyAnimation::ParseParam(Parcel& parcel)
87 {
88     if (!RSRenderAnimation::ParseParam(parcel)) {
89         ROSEN_LOGE("RSRenderPropertyAnimation::ParseParam, RenderAnimation failed");
90         return false;
91     }
92 
93     if (!(parcel.ReadUint64(propertyId_) && RSMarshallingHelper::Unmarshalling(parcel, isAdditive_))) {
94         ROSEN_LOGE("RSRenderPropertyAnimation::ParseParam, Unmarshalling failed");
95         return false;
96     }
97     RS_PROFILER_PATCH_NODE_ID(parcel, propertyId_);
98     if (!RSRenderPropertyBase::Unmarshalling(parcel, originValue_)) {
99         return false;
100     }
101     if (originValue_ == nullptr) {
102         ROSEN_LOGE("RSRenderPropertyAnimation::ParseParam, originValue_ is nullptr!");
103         return false;
104     }
105     lastValue_ = originValue_->Clone();
106 
107     return true;
108 }
109 
SetPropertyValue(const std::shared_ptr<RSRenderPropertyBase> & value)110 void RSRenderPropertyAnimation::SetPropertyValue(const std::shared_ptr<RSRenderPropertyBase>& value)
111 {
112     if (property_ != nullptr) {
113         property_->SetValue(value);
114     }
115 }
116 
GetPropertyValue() const117 const std::shared_ptr<RSRenderPropertyBase> RSRenderPropertyAnimation::GetPropertyValue() const
118 {
119     if (property_ != nullptr) {
120         return property_->Clone();
121     }
122 
123     if (lastValue_ != nullptr) {
124         return lastValue_->Clone();
125     }
126 
127     return nullptr;
128 }
129 
GetOriginValue() const130 const std::shared_ptr<RSRenderPropertyBase>& RSRenderPropertyAnimation::GetOriginValue() const
131 {
132     return originValue_;
133 }
134 
GetLastValue() const135 const std::shared_ptr<RSRenderPropertyBase>& RSRenderPropertyAnimation::GetLastValue() const
136 {
137     return lastValue_;
138 }
139 
SetAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & value)140 void RSRenderPropertyAnimation::SetAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& value)
141 {
142     std::shared_ptr<RSRenderPropertyBase> animationValue;
143     if (GetAdditive() && (property_ != nullptr)) {
144         animationValue = property_->Clone() + (value - lastValue_);
145         lastValue_ = value->Clone();
146     } else {
147         animationValue = value->Clone();
148         lastValue_ = value->Clone();
149     }
150     SetPropertyValue(animationValue);
151 }
152 
GetAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & value)153 const std::shared_ptr<RSRenderPropertyBase> RSRenderPropertyAnimation::GetAnimationValue(
154     const std::shared_ptr<RSRenderPropertyBase>& value)
155 {
156     std::shared_ptr<RSRenderPropertyBase> animationValue;
157     if (GetAdditive()) {
158         animationValue = GetPropertyValue() + (value - lastValue_);
159     } else {
160         animationValue = value->Clone();
161     }
162 
163     lastValue_ = value->Clone();
164     return animationValue;
165 }
166 
OnRemoveOnCompletion()167 void RSRenderPropertyAnimation::OnRemoveOnCompletion()
168 {
169     std::shared_ptr<RSRenderPropertyBase> backwardValue;
170     if (GetAdditive()) {
171         backwardValue = GetPropertyValue() + (GetOriginValue() - lastValue_);
172     } else {
173         backwardValue = GetOriginValue();
174     }
175 
176     SetPropertyValue(backwardValue);
177 }
178 
RecordLastAnimateValue()179 void RSRenderPropertyAnimation::RecordLastAnimateValue()
180 {
181     if (!RSRenderAnimation::isCalcAnimateVelocity_) {
182         return;
183     }
184     animateVelocity_.reset();
185     lastAnimateValue_.reset();
186     if (property_ != nullptr) {
187         lastAnimateValue_ = property_->Clone();
188     }
189 }
190 
UpdateAnimateVelocity(float frameInterval)191 void RSRenderPropertyAnimation::UpdateAnimateVelocity(float frameInterval)
192 {
193     if (!RSRenderAnimation::isCalcAnimateVelocity_ ||
194         !lastAnimateValue_ || !property_ || ROSEN_EQ<float>(frameInterval, 0)) {
195         return;
196     }
197 
198     if (property_->GetPropertyUnit() == RSPropertyUnit::ANGLE_ROTATION) {
199         ProcessAnimateVelocityUnderAngleRotation(frameInterval);
200         return;
201     }
202 
203     if (property_->GetPropertyUnit() > RSPropertyUnit::UNKNOWN) {
204         auto currAnimateValue = property_->Clone();
205         animateVelocity_ = (currAnimateValue - lastAnimateValue_) * (1 / frameInterval);
206         ROSEN_LOGD("%{public}s, currAnimateValue: %{public}f, lastAnimateValue: %{public}f, "
207             "animateVelocity: %{public}f", __func__, currAnimateValue->ToFloat(),
208             lastAnimateValue_->ToFloat(), animateVelocity_->ToFloat());
209     }
210 }
211 
ProcessAnimateVelocityUnderAngleRotation(float frameInterval)212 void RSRenderPropertyAnimation::ProcessAnimateVelocityUnderAngleRotation(float frameInterval)
213 {
214     auto currAnimateValue = property_->Clone();
215     float currAnimateFloatValue = currAnimateValue->ToFloat();
216     auto diffValue = currAnimateValue - lastAnimateValue_;
217     auto diffFloatValue = currAnimateFloatValue - lastAnimateValue_->ToFloat();
218     // 150 means 150 angle.
219     // The angle of the representation varies greatly between two frames.
220     int32_t factor = std::abs(diffFloatValue) / 150;
221     if (factor > 0) {
222         if (ROSEN_EQ<float>(currAnimateFloatValue, 0)) {
223             ROSEN_LOGE("%{public}s, currAnimateFloatValue is 0", __func__);
224             return;
225         }
226         // 180 means 180 angle, relative to pi radian.
227         auto circleValue = currAnimateValue * (180 * factor / currAnimateFloatValue);
228         diffValue = diffFloatValue < 0 ? (currAnimateValue + circleValue) - lastAnimateValue_
229                     : currAnimateValue - (lastAnimateValue_ + circleValue);
230     }
231     if (ROSEN_EQ<float>(frameInterval, 0)) {
232         ROSEN_LOGE("%{public}s, frameInterval is 0", __func__);
233         return;
234     }
235     animateVelocity_ = diffValue * (1 / frameInterval);
236     ROSEN_LOGD("%{public}s, currAnimateValue: %{public}f, lastAnimateValue: %{public}f, "
237         "diffFloatValue: %{public}f, factor: %{public}d, animateVelocity: %{public}f",
238         __func__, currAnimateValue->ToFloat(), lastAnimateValue_->ToFloat(), diffFloatValue,
239         factor, animateVelocity_->ToFloat());
240 }
241 
DumpFraction(float fraction,int64_t time)242 void RSRenderPropertyAnimation::DumpFraction(float fraction, int64_t time)
243 {
244     RSAnimationTraceUtils::GetInstance().addAnimationFrameTrace(
245         GetTargetId(), GetTargetName(), GetAnimationId(), GetPropertyId(), fraction, GetPropertyValue(), time);
246 }
247 } // namespace Rosen
248 } // namespace OHOS
249