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