• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }