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 <memory>
17 #include <string>
18 #include <codecvt>
19 #include <locale>
20
21 #include "common/rs_common_def.h"
22 #include "gfx/fps_info/rs_surface_fps_manager.h"
23
24 namespace OHOS::Rosen {
GetInstance()25 RSSurfaceFpsManager& RSSurfaceFpsManager::GetInstance()
26 {
27 static RSSurfaceFpsManager instance;
28 return instance;
29 }
30
ConvertToLongLongUint(const std::string & str,uint64_t & value,int8_t base=10)31 bool ConvertToLongLongUint(const std::string& str, uint64_t& value, int8_t base = 10)
32 {
33 char* end;
34 errno = 0;
35 value = std::strtoull(str.c_str(), &end, base);
36 if (end == str.c_str()) {
37 return false;
38 }
39 if (errno == ERANGE && value == ULLONG_MAX) {
40 return false;
41 }
42 if (*end != '\0') {
43 return false;
44 }
45 return true;
46 }
47
RegisterSurfaceFps(NodeId id,const std::string & name)48 bool RSSurfaceFpsManager::RegisterSurfaceFps(NodeId id, const std::string& name)
49 {
50 std::unique_lock<std::shared_mutex> lock(smtx);
51 if (surfaceFpsMap_.find(id) != surfaceFpsMap_.end()) {
52 return false;
53 }
54 surfaceFpsMap_[id] = std::make_shared<RSSurfaceFps>(name);
55 return true;
56 }
57
UnregisterSurfaceFps(NodeId id)58 bool RSSurfaceFpsManager::UnregisterSurfaceFps(NodeId id)
59 {
60 std::unique_lock<std::shared_mutex> lock(smtx);
61 if (surfaceFpsMap_.find(id) == surfaceFpsMap_.end()) {
62 return false;
63 }
64 surfaceFpsMap_.erase(id);
65 return true;
66 }
67
GetSurfaceFps(NodeId id)68 std::shared_ptr<RSSurfaceFps> RSSurfaceFpsManager::GetSurfaceFps(NodeId id)
69 {
70 std::shared_lock<std::shared_mutex> lock(smtx);
71 auto iter = surfaceFpsMap_.find(id);
72 if (iter == surfaceFpsMap_.end()) {
73 return nullptr;
74 }
75 return iter->second;
76 }
77
GetSurfaceFps(const std::string & name,bool & isUnique)78 std::shared_ptr<RSSurfaceFps> RSSurfaceFpsManager::GetSurfaceFps(const std::string& name, bool& isUnique)
79 {
80 std::shared_lock<std::shared_mutex> lock(smtx);
81 std::shared_ptr<RSSurfaceFps> surfaceFpsPtr = nullptr;
82 uint8_t sameNameNumber = 0;
83 for (auto [id, surfaceFps] : surfaceFpsMap_) {
84 if (surfaceFps->GetName() == name) {
85 surfaceFpsPtr = surfaceFps;
86 sameNameNumber++;
87 }
88 }
89 isUnique = (sameNameNumber == 1);
90 return surfaceFpsPtr;
91 }
92
GetSurfaceFpsByPid(pid_t pid)93 std::shared_ptr<RSSurfaceFps> RSSurfaceFpsManager::GetSurfaceFpsByPid(pid_t pid)
94 {
95 std::shared_lock<std::shared_mutex> lock(smtx);
96 for (auto [id, surfaceFps] : surfaceFpsMap_) {
97 if (ExtractPid(id) == pid) {
98 return surfaceFps;
99 }
100 }
101 return nullptr;
102 }
103
RecordPresentTime(NodeId id,uint64_t timestamp,uint32_t seqNum)104 bool RSSurfaceFpsManager::RecordPresentTime(NodeId id, uint64_t timestamp, uint32_t seqNum)
105 {
106 const auto& surfaceFps = GetSurfaceFps(id);
107 if (surfaceFps == nullptr) {
108 return false;
109 }
110 return surfaceFps->RecordPresentTime(timestamp, seqNum);
111 }
112
Dump(std::string & result,const std::string & name)113 void RSSurfaceFpsManager::Dump(std::string& result, const std::string& name)
114 {
115 bool isUnique(false);
116 const auto& surfaceFps = GetSurfaceFps(name, isUnique);
117 if (surfaceFps == nullptr) {
118 return ;
119 } else if (!isUnique) {
120 result = "There are multiple surfaces with the same name, please use \"fps -id NodeId\" to query.\n";
121 return ;
122 }
123 result += " surface [" + name + "]:\n";
124 surfaceFps->Dump(result);
125 }
126
ClearDump(std::string & result,const std::string & name)127 void RSSurfaceFpsManager::ClearDump(std::string& result, const std::string& name)
128 {
129 bool isUnique(false);
130 const auto& surfaceFps = GetSurfaceFps(name, isUnique);
131 if (surfaceFps == nullptr) {
132 return ;
133 } else if (!isUnique) {
134 result = "There are multiple surfaces with the same name, please use \"fps -id NodeId\" to query.\n";
135 return ;
136 }
137 result += " The fps info of surface [" + name + "] is cleared.\n";
138 surfaceFps->ClearDump();
139 }
140
Dump(std::string & result,NodeId id)141 void RSSurfaceFpsManager::Dump(std::string& result, NodeId id)
142 {
143 const auto& surfaceFps = GetSurfaceFps(id);
144 if (surfaceFps == nullptr) {
145 return ;
146 }
147 result += " surface [" + surfaceFps->GetName() + "]:\n";
148 surfaceFps->Dump(result);
149 }
150
ClearDump(std::string & result,NodeId id)151 void RSSurfaceFpsManager::ClearDump(std::string& result, NodeId id)
152 {
153 const auto& surfaceFps = GetSurfaceFps(id);
154 if (surfaceFps == nullptr) {
155 return ;
156 }
157 result += " The fps info of surface [" + surfaceFps->GetName() + "] is cleared.\n";
158 surfaceFps->ClearDump();
159 }
160
DumpByPid(std::string & result,pid_t pid)161 void RSSurfaceFpsManager::DumpByPid(std::string& result, pid_t pid)
162 {
163 const auto& surfaceFps = GetSurfaceFpsByPid(pid);
164 if (surfaceFps == nullptr) {
165 return ;
166 }
167 result += " surface [" + surfaceFps->GetName() + "]:\n";
168 surfaceFps->Dump(result);
169 }
170
ClearDumpByPid(std::string & result,pid_t pid)171 void RSSurfaceFpsManager::ClearDumpByPid(std::string& result, pid_t pid)
172 {
173 const auto& surfaceFps = GetSurfaceFpsByPid(pid);
174 if (surfaceFps == nullptr) {
175 return ;
176 }
177 result += " The fps info of surface [" + surfaceFps->GetName() + "] is cleared.\n";
178 surfaceFps->ClearDump();
179 }
180
ProcessParam(const std::unordered_set<std::u16string> & argSets,std::string & option,std::string & argStr)181 void RSSurfaceFpsManager::ProcessParam(
182 const std::unordered_set<std::u16string>& argSets, std::string& option, std::string& argStr)
183 {
184 if (argSets.size() == 1) {
185 option = PARAM_NAME;
186 }
187 for (const std::u16string& arg : argSets) {
188 std::string str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}
189 .to_bytes(arg);
190 if (options.find(str) != options.end()) {
191 option = str;
192 } else {
193 argStr = str;
194 }
195 }
196 return ;
197 }
198
IsSurface(const std::string & option,const std::string & argStr)199 bool RSSurfaceFpsManager::IsSurface(const std::string& option, const std::string& argStr)
200 {
201 return option == PARAM_ID || uniRenderArgs.find(argStr) == uniRenderArgs.end();
202 }
203
DumpSurfaceNodeFps(std::string & dumpString,const std::string & option,const std::string & arg)204 void RSSurfaceFpsManager::DumpSurfaceNodeFps(
205 std::string& dumpString, const std::string& option, const std::string& arg)
206 {
207 dumpString += "\n-- The recently fps records info of screens:\n";
208 if (option == PARAM_NAME) {
209 Dump(dumpString, arg);
210 } else if (option == PARAM_ID) {
211 NodeId nodeId = 0;
212 if (!ConvertToLongLongUint(arg, nodeId)) {
213 dumpString = "The input nodeId is invalid, please re-enter";
214 return ;
215 } else {
216 Dump(dumpString, nodeId);
217 }
218 } else {
219 dumpString = "The input option must be \"-name\" or \"-id\", please re-enter";
220 return ;
221 }
222 }
223
ClearSurfaceNodeFps(std::string & dumpString,const std::string & option,const std::string & arg)224 void RSSurfaceFpsManager::ClearSurfaceNodeFps(
225 std::string& dumpString, const std::string& option, const std::string& arg)
226 {
227 dumpString += "\n-- Clear fps records info of screens:\n";
228 if (option == PARAM_NAME) {
229 ClearDump(dumpString, arg);
230 } else if (option == PARAM_ID) {
231 NodeId nodeId = 0;
232 if (!ConvertToLongLongUint(arg, nodeId)) {
233 dumpString = "The input nodeId is invalid, please re-enter";
234 return ;
235 } else {
236 ClearDump(dumpString, nodeId);
237 }
238 } else {
239 dumpString = "The input option must be \"-name\" or \"-id\", please re-enter";
240 return ;
241 }
242 }
243
GetSurfaceFpsMap() const244 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceFps>> RSSurfaceFpsManager::GetSurfaceFpsMap() const
245 {
246 return surfaceFpsMap_;
247 }
248 }