1 /*
2 * Copyright (c) 2024 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_animation_trace_utils.h"
17
18 #include <sstream>
19
20 #include "common/rs_obj_abs_geometry.h"
21 #include "pipeline/rs_render_node.h"
22 #include "platform/common/rs_log.h"
23 #include "platform/common/rs_system_properties.h"
24 #include "rs_trace.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 constexpr const char* ANIMATION_TRACE_ENABLE_NAME = "persist.rosen.animationtrace.enabled";
30 constexpr const char* GRAPHIC_TEST_MODE_TRACE_NAME = "sys.graphic.openTestModeTrace";
31 }
32 bool RSAnimationTraceUtils::isDebugEnabled_ = false;
33
RSAnimationTraceUtils()34 RSAnimationTraceUtils::RSAnimationTraceUtils()
35 {
36 isDebugEnabled_ = RSSystemProperties::GetAnimationTraceEnabled();
37 RSSystemProperties::WatchSystemProperty(
38 ANIMATION_TRACE_ENABLE_NAME, OnAnimationTraceEnabledChangedCallback, nullptr);
39 RSSystemProperties::WatchSystemProperty(
40 GRAPHIC_TEST_MODE_TRACE_NAME, OnAnimationTraceEnabledChangedCallback, nullptr);
41 }
42
OnAnimationTraceEnabledChangedCallback(const char * key,const char * value,void * context)43 void RSAnimationTraceUtils::OnAnimationTraceEnabledChangedCallback(const char* key, const char* value, void* context)
44 {
45 isDebugEnabled_ = RSSystemProperties::GetAnimationTraceEnabled();
46 }
47
GetColorString(const Color & value) const48 std::string RSAnimationTraceUtils::GetColorString(const Color& value) const
49 {
50 std::string colorString;
51 value.Dump(colorString);
52 return colorString;
53 }
54
ParseRenderPropertyValueInner(const std::shared_ptr<RSRenderPropertyBase> & value) const55 std::string RSAnimationTraceUtils::ParseRenderPropertyValueInner(
56 const std::shared_ptr<RSRenderPropertyBase>& value) const
57 {
58 std::string str;
59 auto propertyType = value->GetPropertyType();
60 switch (propertyType) {
61 case RSPropertyType::FLOAT: {
62 str = "float:" + std::to_string(std::static_pointer_cast<RSRenderAnimatableProperty<float>>(value)->Get());
63 break;
64 }
65 case RSPropertyType::RS_COLOR: {
66 str = GetColorString(std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(value)->Get());
67 break;
68 }
69 case RSPropertyType::QUATERNION: {
70 auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Quaternion>>(value)->Get();
71 str = "Quaternion:x:" + std::to_string(property.x_) + "," + "y:" + std::to_string(property.y_) + "," +
72 "z:" + std::to_string(property.z_) + "," + "w:" + std::to_string(property.w_);
73 break;
74 }
75 case RSPropertyType::VECTOR2F: {
76 auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(value)->Get();
77 str = "Vector2f:x:" + std::to_string(property.x_) + "," + "y:" + std::to_string(property.y_);
78 break;
79 }
80 case RSPropertyType::VECTOR4F: {
81 auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(value)->Get();
82 str = "Vector4f:x:" + std::to_string(property.x_) + "," + "y:" + std::to_string(property.y_) + "," +
83 "z:" + std::to_string(property.z_) + "," + "w:" + std::to_string(property.w_);
84 break;
85 }
86 case RSPropertyType::VECTOR4_COLOR: {
87 auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4<Color>>>(value)->Get();
88 str = "Vector4<Color>:x:" + GetColorString(property.x_) + "," + "y:" + GetColorString(property.y_) + "," +
89 "z:" + GetColorString(property.z_) + "," + "w:" + GetColorString(property.w_);
90 break;
91 }
92 case RSPropertyType::RRECT: {
93 str = "RRECT " + std::static_pointer_cast<RSRenderAnimatableProperty<RRect>>(value)->Get().ToString();
94 break;
95 }
96 default: {
97 str = "None";
98 break;
99 }
100 }
101 return str;
102 }
103
ParseRenderPropertyValue(const std::shared_ptr<RSRenderPropertyBase> & value) const104 std::string RSAnimationTraceUtils::ParseRenderPropertyValue(const std::shared_ptr<RSRenderPropertyBase>& value) const
105 {
106 if (value == nullptr) {
107 return {};
108 }
109 // Cyclomatic complexity exceeds 20
110 return ParseRenderPropertyValueInner(value);
111 }
112
AddAnimationNameTrace(const std::string & str) const113 void RSAnimationTraceUtils::AddAnimationNameTrace(const std::string& str) const
114 {
115 if (isDebugEnabled_) {
116 RS_TRACE_NAME(str.c_str());
117 }
118 }
119
AddAnimationCancelTrace(const uint64_t nodeId,const uint64_t propertyId) const120 void RSAnimationTraceUtils::AddAnimationCancelTrace(const uint64_t nodeId, const uint64_t propertyId) const
121 {
122 if (isDebugEnabled_) {
123 RS_TRACE_NAME_FMT("CancelAnimationByProperty node[%llu] pro[%llu]", nodeId, propertyId);
124 }
125 }
126
AddChangeAnimationValueTrace(const uint64_t propertyId,const std::shared_ptr<RSRenderPropertyBase> & endValue) const127 void RSAnimationTraceUtils::AddChangeAnimationValueTrace(
128 const uint64_t propertyId, const std::shared_ptr<RSRenderPropertyBase>& endValue) const
129 {
130 if (isDebugEnabled_) {
131 auto endStr = ParseRenderPropertyValue(endValue);
132 RS_TRACE_NAME_FMT("animation value be changed pro[%llu] endValue[%s]", propertyId, endStr.c_str());
133 }
134 }
135
AddAnimationFinishTrace(const std::string info,const uint64_t nodeId,const uint64_t animationId,bool isAddLogInfo) const136 void RSAnimationTraceUtils::AddAnimationFinishTrace(
137 const std::string info, const uint64_t nodeId, const uint64_t animationId, bool isAddLogInfo) const
138 {
139 if (isDebugEnabled_) {
140 RS_TRACE_NAME_FMT("%s node[%llu] animate[%llu]", info.c_str(), nodeId, animationId);
141 if (isAddLogInfo) {
142 ROSEN_LOGI("%{public}s node[%{public}" PRIu64 "] animate[%{public}" PRIu64 "]",
143 info.c_str(), nodeId, animationId);
144 }
145 }
146 }
147
GetAnimationTypeString(ImplicitAnimationParamType type) const148 std::string RSAnimationTraceUtils::GetAnimationTypeString(ImplicitAnimationParamType type) const
149 {
150 switch (type) {
151 case ImplicitAnimationParamType::INVALID:
152 return "Invalid";
153 case ImplicitAnimationParamType::CURVE:
154 return "Curve";
155 case ImplicitAnimationParamType::KEYFRAME:
156 return "Keyframe";
157 case ImplicitAnimationParamType::PATH:
158 return "Path";
159 case ImplicitAnimationParamType::SPRING:
160 return "Spring";
161 case ImplicitAnimationParamType::INTERPOLATING_SPRING:
162 return "InterpolatingSpring";
163 case ImplicitAnimationParamType::TRANSITION:
164 return "Transition";
165 case ImplicitAnimationParamType::CANCEL:
166 return "Cancel";
167 default:
168 return "Invalid";
169 }
170 }
171
GetNodeTypeString(RSUINodeType type) const172 std::string RSAnimationTraceUtils::GetNodeTypeString(RSUINodeType type) const
173 {
174 switch (type) {
175 case RSUINodeType::UNKNOW:
176 return "UNKNOW";
177 case RSUINodeType::DISPLAY_NODE:
178 return "DisplayNode";
179 case RSUINodeType::RS_NODE:
180 return "RsNode";
181 case RSUINodeType::SURFACE_NODE:
182 return "SurfaceNode";
183 case RSUINodeType::PROXY_NODE:
184 return "ProxyNode";
185 case RSUINodeType::CANVAS_NODE:
186 return "CanvasNode";
187 case RSUINodeType::ROOT_NODE:
188 return "RootNode";
189 case RSUINodeType::EFFECT_NODE:
190 return "EffectNode";
191 case RSUINodeType::CANVAS_DRAWING_NODE:
192 return "CanvasDrawingNode";
193 default:
194 return "UNKNOW";
195 }
196 }
197
AddAnimationCallFinishTrace(const uint64_t nodeId,const uint64_t animationId,ModifierNG::RSPropertyType propertyType,bool isAddLogInfo) const198 void RSAnimationTraceUtils::AddAnimationCallFinishTrace(
199 const uint64_t nodeId, const uint64_t animationId, ModifierNG::RSPropertyType propertyType, bool isAddLogInfo) const
200 {
201 if (!isDebugEnabled_) {
202 return;
203 }
204 auto propertyTypeStr = ModifierNG::RSModifierTypeString::GetPropertyTypeString(propertyType);
205 RS_TRACE_NAME_FMT("Animation Call FinishCallback node[%llu] animate[%llu] propertyType[%s]", nodeId, animationId,
206 propertyTypeStr.c_str());
207 if (isAddLogInfo) {
208 ROSEN_LOGI("Animation Call FinishCallback node[%{public}" PRIu64 "] animate[%{public}" PRIu64 "]"
209 "propertyType[%{public}s]",
210 nodeId, animationId, propertyTypeStr.c_str());
211 }
212 }
213
AddAnimationCreateTrace(const uint64_t nodeId,const std::string & nodeName,const uint64_t propertyId,const uint64_t animationId,const ImplicitAnimationParamType animationType,const ModifierNG::RSPropertyType propertyType,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const int animationDelay,const int animationDur,const int repeat,const std::string & interfaceName,const int32_t frameNodeId,const std::string & frameNodeTag,RSUINodeType nodeType) const214 void RSAnimationTraceUtils::AddAnimationCreateTrace(const uint64_t nodeId, const std::string& nodeName,
215 const uint64_t propertyId, const uint64_t animationId, const ImplicitAnimationParamType animationType,
216 const ModifierNG::RSPropertyType propertyType, const std::shared_ptr<RSRenderPropertyBase>& startValue,
217 const std::shared_ptr<RSRenderPropertyBase>& endValue, const int animationDelay, const int animationDur,
218 const int repeat, const std::string& interfaceName, const int32_t frameNodeId, const std::string& frameNodeTag,
219 RSUINodeType nodeType) const
220 {
221 if (!isDebugEnabled_) {
222 return;
223 }
224
225 std::ostringstream oss;
226 oss << "CreateImplicitAnimation node[" << nodeId << "]";
227
228 if (!nodeName.empty()) {
229 oss << " name[" << nodeName << "]";
230 }
231
232 oss << " animate[" << animationId << "] animateType[" << GetAnimationTypeString(animationType) << "] dur["
233 << animationDur << "]";
234
235 if (animationDelay != 0) {
236 oss << " delay[" << animationDelay << "]";
237 }
238
239 if (repeat != 1) {
240 oss << " repeat[" << repeat << "]";
241 }
242
243 if (!interfaceName.empty()) {
244 oss << " interfaceName[" << interfaceName << "]";
245 }
246
247 oss << " frameNodeId[" << frameNodeId << "] frameNodeTag[" << frameNodeTag << "] nodeType["
248 << GetNodeTypeString(nodeType) << "]";
249
250 RS_TRACE_NAME_FMT("%s", oss.str().c_str());
251
252 std::ostringstream propertyOss;
253 propertyOss << "CreateImplicitAnimation pro[" << propertyId << "] propertyType["
254 << ModifierNG::RSModifierTypeString::GetPropertyTypeString(propertyType) << "] startValue["
255 << ParseRenderPropertyValue(startValue) << "] endValue[" << ParseRenderPropertyValue(endValue) << "]";
256
257 RS_TRACE_NAME_FMT("%s", propertyOss.str().c_str());
258 }
259
AddAnimationFrameTrace(const RSRenderNode * target,const uint64_t nodeId,const std::string & nodeName,const uint64_t animationId,const uint64_t propertyId,const float fraction,const std::shared_ptr<RSRenderPropertyBase> & value,const int64_t time,const int dur,const int repeat) const260 void RSAnimationTraceUtils::AddAnimationFrameTrace(const RSRenderNode* target, const uint64_t nodeId,
261 const std::string& nodeName, const uint64_t animationId, const uint64_t propertyId, const float fraction,
262 const std::shared_ptr<RSRenderPropertyBase>& value, const int64_t time, const int dur, const int repeat) const
263 {
264 if (!isDebugEnabled_) {
265 return;
266 }
267
268 auto propertyValue = ParseRenderPropertyValue(value);
269 // If it's a UI animation, target is always nullptr. Check if nodeId is not 0. If yes, the animation stays on the
270 // node tree by default.
271 bool isOnTheTree = target ? target->IsOnTheTree() : (nodeId != 0);
272
273 std::ostringstream oss;
274 oss << "frame animation node[" << nodeId << "]";
275
276 if (!nodeName.empty()) {
277 oss << " name[" << nodeName << "]";
278 }
279
280 if (!isOnTheTree) {
281 oss << " onTree[" << isOnTheTree << "]";
282 }
283
284 oss << " pro[" << propertyId << "]";
285 oss << " animate[" << animationId << "]";
286 oss << " fraction[" << fraction << "]";
287 oss << " value[" << propertyValue << "]";
288 oss << " time[" << time << "]";
289 oss << " dur[" << dur << "]";
290
291 if (repeat != 1) {
292 oss << " repeat[" << repeat << "]";
293 }
294
295 RS_TRACE_NAME_FMT("%s", oss.str().c_str());
296 }
297
AddSpringInitialVelocityTrace(const uint64_t propertyId,const uint64_t animationId,const std::shared_ptr<RSRenderPropertyBase> & initialVelocity,const std::shared_ptr<RSRenderPropertyBase> & value) const298 void RSAnimationTraceUtils::AddSpringInitialVelocityTrace(const uint64_t propertyId, const uint64_t animationId,
299 const std::shared_ptr<RSRenderPropertyBase>& initialVelocity,
300 const std::shared_ptr<RSRenderPropertyBase>& value) const
301 {
302 if (isDebugEnabled_) {
303 auto propertyValue = ParseRenderPropertyValue(initialVelocity);
304 RS_TRACE_NAME_FMT("spring pro[%llu] animate[%llu], initialVelocity[%s]",
305 propertyId, animationId, propertyValue.c_str());
306 }
307 }
308
309 } // namespace Rosen
310 } // namespace OHOS