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 "common/rs_obj_abs_geometry.h"
19 #include "pipeline/rs_render_node.h"
20 #include "platform/common/rs_log.h"
21 #include "platform/common/rs_system_properties.h"
22 #include "rs_trace.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 RSAnimationTraceUtils RSAnimationTraceUtils::instance_;
27 
RSAnimationTraceUtils()28 RSAnimationTraceUtils::RSAnimationTraceUtils()
29 {
30     isDebugOpen_ = RSSystemProperties::GetAnimationTraceEnabled();
31 }
32 
ParseRenderPropertyVauleInner(const std::shared_ptr<RSRenderPropertyBase> & value,const RSRenderPropertyType type) const33 std::string RSAnimationTraceUtils::ParseRenderPropertyVauleInner(
34     const std::shared_ptr<RSRenderPropertyBase>& value, const RSRenderPropertyType type) const
35 {
36     std::string str;
37     auto propertyType = value->GetPropertyType() == RSRenderPropertyType::INVALID ? type : value->GetPropertyType();
38     switch (propertyType) {
39         case RSRenderPropertyType::PROPERTY_FLOAT: {
40             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<float>>(value);
41             if (property) {
42                 str = "float:" + std::to_string(property->Get());
43             }
44             break;
45         }
46         case RSRenderPropertyType::PROPERTY_COLOR: {
47             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Color>>(value);
48             if (property) {
49                 str = "Color:" + std::to_string(property->Get().AsRgbaInt());
50             }
51             break;
52         }
53         case RSRenderPropertyType::PROPERTY_MATRIX3F: {
54             str = "Matrix3f";
55             break;
56         }
57         case RSRenderPropertyType::PROPERTY_QUATERNION: {
58             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Quaternion>>(value);
59             if (property) {
60                 str = "Quaternion:x:" + std::to_string(property->Get().x_) + "," +
61                       "y:" + std::to_string(property->Get().y_) + "," +
62                       "z:" + std::to_string(property->Get().z_) + "," +
63                       "w:" + std::to_string(property->Get().w_);
64             }
65             break;
66         }
67         case RSRenderPropertyType::PROPERTY_FILTER: {
68             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<std::shared_ptr<RSFilter>>>(value);
69             if (property && property->Get()) {
70                 str = property->Get()->GetDescription();
71             } else {
72                 str = "FILTER";
73             }
74             break;
75         }
76         case RSRenderPropertyType::PROPERTY_VECTOR2F: {
77             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector2f>>(value);
78             if (property) {
79                 str = "Vector2f:x:" + std::to_string(property->Get().x_) + "," +
80                       "y:" + std::to_string(property->Get().y_);
81             }
82             break;
83         }
84         case RSRenderPropertyType::PROPERTY_VECTOR4F: {
85             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4f>>(value);
86             if (property) {
87                 str = "Vector4f:x:" + std::to_string(property->Get().x_) + "," +
88                       "y:" + std::to_string(property->Get().y_) + "," +
89                       "z:" + std::to_string(property->Get().z_) + "," +
90                       "w:" + std::to_string(property->Get().w_);
91             }
92             break;
93         }
94         case RSRenderPropertyType::PROPERTY_VECTOR4_COLOR: {
95             auto property = std::static_pointer_cast<RSRenderAnimatableProperty<Vector4<Color>>>(value);
96             if (property) {
97                 str = "Vector4<Color>:x:" + std::to_string(property->Get().x_.AsRgbaInt()) + "," +
98                       "y:" + std::to_string(property->Get().y_.AsRgbaInt()) + "," +
99                       "z:" + std::to_string(property->Get().z_.AsRgbaInt()) + "," +
100                       "w:" + std::to_string(property->Get().w_.AsRgbaInt());
101             }
102             break;
103         }
104         default: {
105             str = "None";
106             break;
107         }
108     }
109     return str;
110 }
111 
ParseRenderPropertyVaule(const std::shared_ptr<RSRenderPropertyBase> & value,const RSRenderPropertyType type) const112 std::string RSAnimationTraceUtils::ParseRenderPropertyVaule(
113     const std::shared_ptr<RSRenderPropertyBase>& value, const RSRenderPropertyType type) const
114 {
115     if (value == nullptr) {
116         return std::string();
117     }
118     // Cyclomatic complexity exceeds 20
119     return ParseRenderPropertyVauleInner(value, type);
120 }
121 
addAnimationNameTrace(const std::string str) const122 void RSAnimationTraceUtils::addAnimationNameTrace(const std::string str) const
123 {
124     if (isDebugOpen_) {
125         RS_TRACE_NAME(str.c_str());
126     }
127 }
128 
addAnimationFinishTrace(const std::string info,const uint64_t nodeId,const uint64_t animationId,bool isAddLogInfo) const129 void RSAnimationTraceUtils::addAnimationFinishTrace(
130     const std::string info, const uint64_t nodeId, const uint64_t animationId, bool isAddLogInfo) const
131 {
132     if (isDebugOpen_) {
133         RS_TRACE_NAME_FMT("%s node[%llu] animate[%llu]", info.c_str(), nodeId, animationId);
134         if (isAddLogInfo) {
135             ROSEN_LOGI("%{public}s node[%{public}" PRIu64 "] animate[%{public}" PRIu64 "]",
136                 info.c_str(), nodeId, animationId);
137         }
138     }
139 }
140 
addAnimationCreateTrace(const uint64_t nodeId,const std::string & nodeName,const uint64_t propertyId,const uint64_t animationId,const int animationType,const int propertyType,const std::shared_ptr<RSRenderPropertyBase> & startValue,const std::shared_ptr<RSRenderPropertyBase> & endValue,const int animationDelay,const int animationDur,const int repeat) const141 void RSAnimationTraceUtils::addAnimationCreateTrace(const uint64_t nodeId, const std::string& nodeName,
142     const uint64_t propertyId, const uint64_t animationId, const int animationType, const int propertyType,
143     const std::shared_ptr<RSRenderPropertyBase>& startValue, const std::shared_ptr<RSRenderPropertyBase>& endValue,
144     const int animationDelay, const int animationDur, const int repeat) const
145 {
146     if (isDebugOpen_) {
147         auto startStr = ParseRenderPropertyVaule(startValue);
148         auto endStr = ParseRenderPropertyVaule(endValue);
149         RS_TRACE_NAME_FMT(
150             "CreateImplicitAnimation node[%llu] name[%s] pro[%llu] animate[%llu], animateType %d, propertyType %d, "
151             "startValue[%s], endValue[%s], delay %d, dur %d repeat %d",
152             nodeId, nodeName.c_str(), propertyId, animationId, animationType, propertyType, startStr.c_str(),
153             endStr.c_str(), animationDelay, animationDur, repeat);
154     }
155 }
156 
addAnimationFrameTrace(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) const157 void RSAnimationTraceUtils::addAnimationFrameTrace(const uint64_t nodeId, const std::string& nodeName,
158     const uint64_t animationId, const uint64_t propertyId, const float fraction,
159     const std::shared_ptr<RSRenderPropertyBase>& value, const int64_t time) const
160 {
161     if (isDebugOpen_) {
162         auto propertyValue = ParseRenderPropertyVaule(value);
163         RS_TRACE_NAME_FMT(
164             "frame animation node[%llu] name[%s] pro[%llu] animate[%llu], fraction %f, value[%s], time[%lld]", nodeId,
165             nodeName.c_str(), propertyId, animationId, fraction, propertyValue.c_str(), time);
166     }
167 }
168 
addSpringInitialVelocityTrace(const uint64_t propertyId,const uint64_t animationId,const std::shared_ptr<RSRenderPropertyBase> & initialVelocity,const std::shared_ptr<RSRenderPropertyBase> & value) const169 void RSAnimationTraceUtils::addSpringInitialVelocityTrace(const uint64_t propertyId, const uint64_t animationId,
170     const std::shared_ptr<RSRenderPropertyBase>& initialVelocity,
171     const std::shared_ptr<RSRenderPropertyBase>& value) const
172 {
173     if (isDebugOpen_) {
174         auto propertyValue = ParseRenderPropertyVaule(initialVelocity, value->GetPropertyType());
175         RS_TRACE_NAME_FMT("spring pro[%llu] animate[%llu], initialVelocity[%s]",
176             propertyId, animationId, propertyValue.c_str());
177     }
178 }
179 
addRenderNodeTrace(const RSRenderNode & node,const std::string name) const180 void RSAnimationTraceUtils::addRenderNodeTrace(const RSRenderNode& node, const std::string name) const
181 {
182     if (!isDebugOpen_) {
183         return;
184     }
185     [[maybe_unused]] auto alpha = node.GetGlobalAlpha();
186     [[maybe_unused]] auto rotation = node.GetRenderProperties().GetRotation();
187     [[maybe_unused]] auto bounds = node.GetRenderProperties().GetBoundsRect().ToString();
188     [[maybe_unused]] auto translateX = node.GetRenderProperties().GetTranslateX();
189     [[maybe_unused]] auto translateY = node.GetRenderProperties().GetTranslateY();
190     [[maybe_unused]] auto absRect =
191         std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry())->GetAbsRect()
192             .ToString();
193     [[maybe_unused]] auto scaleX = node.GetRenderProperties().GetScaleX();
194     [[maybe_unused]] auto scaleY = node.GetRenderProperties().GetScaleY();
195     [[maybe_unused]] auto cornerRadius = node.GetRenderProperties().GetCornerRadius().x_;
196     std::string nameStr;
197     if (name.empty()) {
198         nameStr = "ProcessCanvasRenderNode:";
199     } else {
200         nameStr = "ProcessSurfaceRenderNode:name " + name;
201     }
202     RS_TRACE_NAME_FMT("%s node[%llu] alpha %f rotation %f bounds %s, translateX %f translateY %f absRect %s, " \
203                       "scaleX %f scaleY %f cornerRadius %f",
204         nameStr.c_str(), node.GetId(), alpha, rotation, bounds.c_str(), translateX, translateY, absRect.c_str(),
205         scaleX, scaleY, cornerRadius);
206 }
207 } // namespace Rosen
208 } // namespace OHOS