• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "property/rs_property_trace.h"
17 
18 #include <climits>
19 #include <cstdarg>
20 #include <fstream>
21 #include <regex>
22 #include <securec.h>
23 #include <sys/time.h>
24 #include "directory_ex.h"
25 
26 #include "rs_trace.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 const std::string ANIMATION_LOG_PATH = "/etc/rosen/";
31 const std::string CONFIG_FILE_NAME = "property.config";
32 const std::string COLON_SEPARATOR = ":";
33 const std::string COMMA_SEPARATOR = ",";
34 const std::string SEMICOLON_SEPARATOR = ";";
35 const std::string NODE_ID_TAG = "ID";
36 const std::string PROPERTY_ID_TAG = "PROPERTY";
37 const std::string ALL_NEED_TAG = "all";
38 const std::string CORNER_PROPERTY_TAG = "corner";
39 const std::string ALPHA_PROPERTY_TAG = "alpha";
40 const std::string SHADOW_PROPERTY_TAG = "shadow";
41 static constexpr int MIN_INFO_SIZE = 2;
42 RSPropertyTrace RSPropertyTrace::instance_;
43 
PropertiesDisplayByTrace(const NodeId & id,const RSProperties & properties)44 void RSPropertyTrace::PropertiesDisplayByTrace(const NodeId& id, const RSProperties& properties)
45 {
46     if (IsNeedPropertyTrace(id)) {
47         auto rectI = (properties.GetBoundsGeometry())->GetAbsRect();
48         std::string str = std::to_string(id) + " Geometry Rect: " + rectI.ToString();
49         for (auto property : propertySet_) {
50             if (property == CORNER_PROPERTY_TAG) {
51                 auto corner = properties.GetCornerRadius();
52                 str = str + " Corner:(" + std::to_string(corner.x_) +
53                     "," + std::to_string(corner.y_) +
54                     "," + std::to_string(corner.z_) +
55                     "," + std::to_string(corner.w_) + ")";
56             } else if (property == ALPHA_PROPERTY_TAG) {
57                 auto alpha = properties.GetAlpha();
58                 str = str + " Alpha:" + std::to_string(alpha);
59             } else if (property == SHADOW_PROPERTY_TAG) {
60                 auto shadowColor = properties.GetShadowColor();
61                 auto shadowAlpha = properties.GetShadowAlpha();
62                 auto shadowOffsetX = properties.GetShadowOffsetX();
63                 auto shadowOffsetY = properties.GetShadowOffsetY();
64                 auto shadowRadius = properties.GetShadowRadius();
65                 auto shadowElevation = properties.GetShadowElevation();
66                 str = str + " Shadow:{color:(" + std::to_string(shadowColor.GetRed()) +
67                     "," + std::to_string(shadowColor.GetGreen()) +
68                     "," + std::to_string(shadowColor.GetBlue()) +
69                     "),offset:(" + std::to_string(shadowOffsetX) +
70                     "," + std::to_string(shadowOffsetY) +
71                     "),radius:" + std::to_string(shadowRadius) +
72                     ",elevation:" + std::to_string(shadowElevation) +
73                     ",alpha:" + std::to_string(shadowAlpha) + "}";
74             }
75         }
76         AddTraceFlag(str);
77     }
78 }
79 
RefreshNodeTraceInfo()80 void RSPropertyTrace::RefreshNodeTraceInfo()
81 {
82     if (IsNeedRefreshConfig()) {
83         ClearNodeAndPropertyInfo();
84         InitNodeAndPropertyInfo();
85     }
86 }
87 
AddTraceFlag(const std::string & str)88 void RSPropertyTrace::AddTraceFlag(const std::string& str)
89 {
90     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, str.c_str());
91     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
92 }
93 
SplitStringBySeparator(const std::string & str,const std::string & separator)94 std::vector<std::string> SplitStringBySeparator(const std::string& str,
95     const std::string& separator)
96 {
97     std::regex re(separator);
98     std::sregex_token_iterator pos(str.begin(), str.end(), re, -1);
99     std::sregex_token_iterator endPos;
100     std::vector<std::string> result;
101     while (pos != endPos) {
102         result.emplace_back(*pos++);
103     }
104     return result;
105 }
106 
InitNodeAndPropertyInfo()107 void RSPropertyTrace::InitNodeAndPropertyInfo()
108 {
109     std::string configFilePath = ANIMATION_LOG_PATH + CONFIG_FILE_NAME;
110     std::string newpath;
111     if (!PathToRealPath(configFilePath, newpath)) {
112         ROSEN_LOGE("Render node trace config file is nullptr!");
113         return;
114     }
115     std::ifstream configFile(newpath);
116     if (!configFile.is_open()) {
117         ROSEN_LOGE("Open render node trace config file failed!");
118         return;
119     }
120 
121     std::string info;
122     while (std::getline(configFile, info)) {
123         std::vector<std::string> infos = SplitStringBySeparator(info, SEMICOLON_SEPARATOR);
124         if (infos.empty()) {
125             continue;
126         }
127         DealConfigInputInfo(infos.front());
128     }
129     configFile.close();
130 }
131 
DealConfigInputInfo(const std::string & info)132 void RSPropertyTrace::DealConfigInputInfo(const std::string& info)
133 {
134     std::vector<std::string> splitResult = SplitStringBySeparator(info, COLON_SEPARATOR);
135     if (splitResult.size() != MIN_INFO_SIZE) {
136         ROSEN_LOGE("Render node trace config file size error!");
137         return;
138     }
139 
140     std::string tag = splitResult.front();
141     if (tag == NODE_ID_TAG) {
142         std::vector<std::string> nodeIds =
143             SplitStringBySeparator(splitResult.back(), COMMA_SEPARATOR);
144         for (std::string nodeId : nodeIds) {
145             if (nodeId == ALL_NEED_TAG) {
146                 needWriteAllNode_ = true;
147                 return;
148             }
149             auto id = atoll(nodeId.c_str());
150             nodeIdSet_.insert(id);
151         }
152     } else if (tag == PROPERTY_ID_TAG) {
153         std::vector<std::string> propertys =
154             SplitStringBySeparator(splitResult.back(), COMMA_SEPARATOR);
155         for (std::string property : propertys) {
156             propertySet_.insert(property);
157         }
158     }
159 }
160 
ClearNodeAndPropertyInfo()161 void RSPropertyTrace::ClearNodeAndPropertyInfo()
162 {
163     nodeIdSet_.clear();
164     propertySet_.clear();
165 }
166 
IsNeedRefreshConfig()167 bool RSPropertyTrace::IsNeedRefreshConfig()
168 {
169     struct stat configFileStatus = {};
170     std::string configFilePath = ANIMATION_LOG_PATH + CONFIG_FILE_NAME;
171     if (stat(configFilePath.c_str(), &configFileStatus)) {
172         return false;
173     }
174 
175     std::string curent(ctime(&configFileStatus.st_mtime));
176     if (curent != propertyFileLastModifyTime) {
177         propertyFileLastModifyTime = curent;
178         return true;
179     }
180     return false;
181 }
182 
IsNeedPropertyTrace(const NodeId & id)183 bool RSPropertyTrace::IsNeedPropertyTrace(const NodeId& id)
184 {
185     auto itrn = nodeIdSet_.find(id);
186     if (itrn == nodeIdSet_.end() && !needWriteAllNode_) {
187         return false;
188     }
189     return true;
190 }
191 } // namespace Rosen
192 } // namespace OHOS
193