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
DumpAnimationInfo(std::string & out) const31 void RSRenderPropertyAnimation::DumpAnimationInfo(std::string& out) const
32 {
33 out += "Type:RSRenderPropertyAnimation";
34 RSRenderPropertyType type = RSRenderPropertyType::INVALID;
35 if (property_ != nullptr) {
36 type = property_->GetPropertyType();
37 out += ", ModifierType: " + std::to_string(static_cast<int16_t>(property_->GetModifierType()));
38 } else {
39 out += ", ModifierType: INVALID";
40 }
41 }
42
GetPropertyId() const43 PropertyId RSRenderPropertyAnimation::GetPropertyId() const
44 {
45 return propertyId_;
46 }
47
SetAdditive(bool isAdditive)48 void RSRenderPropertyAnimation::SetAdditive(bool isAdditive)
49 {
50 if (IsStarted()) {
51 ROSEN_LOGE("Failed to set additive, animation has started!");
52 return;
53 }
54
55 isAdditive_ = isAdditive;
56 }
57
GetAdditive()58 bool RSRenderPropertyAnimation::GetAdditive()
59 {
60 return isAdditive_;
61 }
62
AttachRenderProperty(const std::shared_ptr<RSRenderPropertyBase> & property)63 void RSRenderPropertyAnimation::AttachRenderProperty(const std::shared_ptr<RSRenderPropertyBase>& property)
64 {
65 property_ = property;
66 if (property_ == nullptr) {
67 return;
68 }
69 InitValueEstimator();
70 if (originValue_ != nullptr) {
71 property_->SetPropertyType(originValue_->GetPropertyType());
72 }
73 }
74
SetPropertyValue(const std::shared_ptr<RSRenderPropertyBase> & value)75 void RSRenderPropertyAnimation::SetPropertyValue(const std::shared_ptr<RSRenderPropertyBase>& value)
76 {
77 if (property_ != nullptr) {
78 property_->SetValue(value);
79 }
80 }
81
GetPropertyValue() const82 const std::shared_ptr<RSRenderPropertyBase> RSRenderPropertyAnimation::GetPropertyValue() const
83 {
84 if (property_ != nullptr) {
85 return property_->Clone();
86 }
87
88 if (lastValue_ != nullptr) {
89 return lastValue_->Clone();
90 }
91
92 return nullptr;
93 }
94
GetOriginValue() const95 const std::shared_ptr<RSRenderPropertyBase>& RSRenderPropertyAnimation::GetOriginValue() const
96 {
97 return originValue_;
98 }
99
GetLastValue() const100 const std::shared_ptr<RSRenderPropertyBase>& RSRenderPropertyAnimation::GetLastValue() const
101 {
102 return lastValue_;
103 }
104
SetAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & value)105 void RSRenderPropertyAnimation::SetAnimationValue(const std::shared_ptr<RSRenderPropertyBase>& value)
106 {
107 if (value == nullptr) {
108 ROSEN_LOGD("RSRenderPropertyAnimation::SetAnimationValue, input is null!");
109 return;
110 }
111 std::shared_ptr<RSRenderPropertyBase> animationValue;
112 if (GetAdditive() && (property_ != nullptr)) {
113 animationValue = property_->Clone() + (value - lastValue_);
114 lastValue_ = value->Clone();
115 } else {
116 animationValue = value->Clone();
117 lastValue_ = value->Clone();
118 }
119 SetPropertyValue(animationValue);
120 }
121
GetAnimationValue(const std::shared_ptr<RSRenderPropertyBase> & value)122 const std::shared_ptr<RSRenderPropertyBase> RSRenderPropertyAnimation::GetAnimationValue(
123 const std::shared_ptr<RSRenderPropertyBase>& value)
124 {
125 if (value == nullptr) {
126 ROSEN_LOGD("RSRenderPropertyAnimation::GetAnimationValue, input is null!");
127 return value;
128 }
129 std::shared_ptr<RSRenderPropertyBase> animationValue;
130 if (GetAdditive()) {
131 animationValue = GetPropertyValue() + (value - lastValue_);
132 } else {
133 animationValue = value->Clone();
134 }
135
136 lastValue_ = value->Clone();
137 return animationValue;
138 }
139
OnRemoveOnCompletion()140 void RSRenderPropertyAnimation::OnRemoveOnCompletion()
141 {
142 std::shared_ptr<RSRenderPropertyBase> backwardValue;
143 if (GetAdditive()) {
144 backwardValue = GetPropertyValue() + (GetOriginValue() - lastValue_);
145 } else {
146 backwardValue = GetOriginValue();
147 }
148
149 SetPropertyValue(backwardValue);
150 }
151
RecordLastAnimateValue()152 void RSRenderPropertyAnimation::RecordLastAnimateValue()
153 {
154 if (!RSRenderAnimation::isCalcAnimateVelocity_) {
155 return;
156 }
157 animateVelocity_.reset();
158 lastAnimateValue_.reset();
159 if (property_ != nullptr) {
160 lastAnimateValue_ = property_->Clone();
161 }
162 }
163
UpdateAnimateVelocity(float frameInterval)164 void RSRenderPropertyAnimation::UpdateAnimateVelocity(float frameInterval)
165 {
166 if (!RSRenderAnimation::isCalcAnimateVelocity_ ||
167 !lastAnimateValue_ || !property_ || ROSEN_EQ<float>(frameInterval, 0)) {
168 return;
169 }
170
171 if (property_->GetPropertyUnit() == RSPropertyUnit::ANGLE_ROTATION) {
172 ProcessAnimateVelocityUnderAngleRotation(frameInterval);
173 return;
174 }
175
176 if (property_->GetPropertyUnit() > RSPropertyUnit::UNKNOWN) {
177 auto currAnimateValue = property_->Clone();
178 animateVelocity_ = (currAnimateValue - lastAnimateValue_) * (1 / frameInterval);
179 ROSEN_LOGD("%{public}s, currAnimateValue: %{public}f, lastAnimateValue: %{public}f, "
180 "animateVelocity: %{public}f", __func__, currAnimateValue->ToFloat(),
181 lastAnimateValue_->ToFloat(), animateVelocity_->ToFloat());
182 }
183 }
184
ProcessAnimateVelocityUnderAngleRotation(float frameInterval)185 void RSRenderPropertyAnimation::ProcessAnimateVelocityUnderAngleRotation(float frameInterval)
186 {
187 auto currAnimateValue = property_->Clone();
188 if (currAnimateValue == nullptr) {
189 ROSEN_LOGE("%{public}s, currAnimateValue is null", __func__);
190 return;
191 }
192 float currAnimateFloatValue = currAnimateValue->ToFloat();
193 auto diffValue = currAnimateValue - lastAnimateValue_;
194 auto diffFloatValue = currAnimateFloatValue - lastAnimateValue_->ToFloat();
195 // 150 means 150 angle.
196 // The angle of the representation varies greatly between two frames.
197 int32_t factor = std::abs(diffFloatValue) / 150;
198 if (factor > 0) {
199 if (ROSEN_EQ<float>(currAnimateFloatValue, 0)) {
200 ROSEN_LOGE("%{public}s, currAnimateFloatValue is 0", __func__);
201 return;
202 }
203 // 180 means 180 angle, relative to pi radian.
204 auto circleValue = currAnimateValue * (180 * factor / currAnimateFloatValue);
205 diffValue = diffFloatValue < 0 ? (currAnimateValue + circleValue) - lastAnimateValue_
206 : currAnimateValue - (lastAnimateValue_ + circleValue);
207 }
208 if (ROSEN_EQ<float>(frameInterval, 0)) {
209 ROSEN_LOGE("%{public}s, frameInterval is 0", __func__);
210 return;
211 }
212 animateVelocity_ = diffValue * (1 / frameInterval);
213 ROSEN_LOGD("%{public}s, currAnimateValue: %{public}f, lastAnimateValue: %{public}f, "
214 "diffFloatValue: %{public}f, factor: %{public}d, animateVelocity: %{public}f",
215 __func__, currAnimateValue->ToFloat(), lastAnimateValue_->ToFloat(), diffFloatValue,
216 factor, animateVelocity_->ToFloat());
217 }
218
DumpFraction(float fraction,int64_t time)219 void RSRenderPropertyAnimation::DumpFraction(float fraction, int64_t time)
220 {
221 RSAnimationTraceUtils::GetInstance().addAnimationFrameTrace(GetTargetId(), GetTargetName(), GetAnimationId(),
222 GetPropertyId(), fraction, GetPropertyValue(), time, GetDuration(), GetRepeatCount());
223 }
224 } // namespace Rosen
225 } // namespace OHOS
226