• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 #include <cstdio>
16 #include <algorithm>
17 #include <iostream>
18 #include <sstream>
19 #include <queue>
20 #include <vector>
21 #include <map>
22 #include <string>
23 #include <unistd.h>
24 #include <sys/time.h>
25 
26 namespace {
27 struct DumpEntity {
28     const std::string windowName;
29     const std::string displayId;
30     const std::string pid;
31     const std::string windId;
32 };
33 struct FpsInfo {
34     int fps;
35     int preFps;
36     std::vector<long long> jitters;
37     std::queue<long long> timeStampQ;
38     long long lastFrameReadyTime;
39     long long currentFpsTime;
FpsInfo__anon60f48c330111::FpsInfo40     FpsInfo()
41     {
42         fps = 0;
43         preFps = 0;
44         lastFrameReadyTime = 0;
45         currentFpsTime = 0;
46     }
47 };
48 struct FpsConfig {
49     const long long mod = 1e9;
50     long long lastReadyTime;
51     int fpsGb;
52     bool jump;
53     bool refresh;
54     int cnt;
55     int zeroNum;
FpsConfig__anon60f48c330111::FpsConfig56     FpsConfig()
57     {
58         lastReadyTime = -1;
59         fpsGb = 0;
60         jump = false;
61         refresh = false;
62         cnt = 0;
63         zeroNum = 0;
64     }
65 };
66 }
StrSplit(const std::string & content,const std::string & sp,std::vector<std::string> & out)67 static void StrSplit(const std::string &content, const std::string &sp, std::vector<std::string> &out)
68 {
69     size_t index = 0;
70     while (index != std::string::npos) {
71         size_t tEnd = content.find_first_of(sp, index);
72         std::string tmp = content.substr(index, tEnd - index);
73         if (tmp != "" && tmp != " ") {
74             out.push_back(tmp);
75         }
76         if (tEnd == std::string::npos) {
77             break;
78         }
79         index = tEnd + 1;
80     }
81 }
82 
GetLayer()83 static std::string GetLayer()
84 {
85     std::vector<DumpEntity> dumpEntityList;
86     std::string curFocusId = "-1";
87     const std::string cmd = "hidumper -s WindowManagerService -a -a";
88     std::string cmdExc = cmd;
89     FILE *fd = popen(cmdExc.c_str(), "r");
90     if (fd != nullptr) {
91         int lineNum = 0;
92         std::string line;
93         char buf[1024] = {'\0'};
94         const int paramFifteen = 15;
95         const int paramThree = 3;
96         const int windowNameIndex = 0;
97         const int windowIdIndex = 3;
98         const int focusNameIndex = 2;
99         while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
100             line = buf;
101             if (line[0] == '-' || line[0] == ' ') {
102                 continue;
103             }
104             std::vector<std::string> params;
105             StrSplit(line, " ", params);
106             if (params[windowNameIndex].find("WindowName")!= std::string::npos &&
107                 params[windowIdIndex].find("WinId")!= std::string::npos) {
108                 continue;
109             }
110             if (params.size() == paramFifteen) {
111                 DumpEntity dumpEntity { params[0], params[1], params[2], params[3] };
112                 dumpEntityList.push_back(dumpEntity);
113             }
114             if (params.size() == paramThree) {
115                 curFocusId = params[focusNameIndex];
116                 break;
117             }
118             lineNum++;
119         }
120         pclose(fd);
121     }
122     std::string resultWindowName = "NA";
123     int curId = std::stoi(curFocusId);
124     for (size_t i = 0; i < dumpEntityList.size(); i++) {
125         DumpEntity dumpItem = dumpEntityList[i];
126         int curWinId = std::stoi(dumpItem.windId);
127         if (curId == curWinId) {
128             resultWindowName = dumpItem.windowName;
129         }
130     }
131     return resultWindowName;
132 }
ProcessResult(FILE * fp,FpsConfig & fpsConfig,FpsInfo & fpsInfo)133 static void ProcessResult(FILE *fp, FpsConfig &fpsConfig, FpsInfo &fpsInfo)
134 {
135     char tmp[1024];
136     while (fgets(tmp, sizeof(tmp), fp) != nullptr) {
137         long long frameReadyTime = 0;
138         std::stringstream sstream;
139         sstream << tmp;
140         sstream >> frameReadyTime;
141         fpsConfig.cnt++;
142         if (frameReadyTime == 0) {
143             fpsConfig.zeroNum++;
144             continue;
145         }
146         if (fpsConfig.lastReadyTime >= frameReadyTime) {
147             fpsConfig.lastReadyTime = -1;
148             continue;
149         }
150         fpsConfig.refresh = true;
151         long long tFrameReadyTime = frameReadyTime / fpsConfig.mod;
152         long long tLastReadyTime = fpsConfig.lastReadyTime / fpsConfig.mod;
153         long long lastFrame = -1;
154         if (tFrameReadyTime == tLastReadyTime) {
155             (fpsInfo.timeStampQ).push(frameReadyTime);
156         } else if (tFrameReadyTime == tLastReadyTime + 1) {
157             fpsConfig.jump = true;
158             lastFrame = fpsInfo.lastFrameReadyTime;
159             fpsConfig.lastReadyTime = frameReadyTime;
160             int fpsTmp = 0;
161             fpsInfo.jitters.clear();
162             while (!(fpsInfo.timeStampQ).empty()) {
163                 fpsTmp++;
164                 long long currFrame = (fpsInfo.timeStampQ.front());
165                 if (lastFrame != -1) {
166                     long long jitter = currFrame - lastFrame;
167                     fpsInfo.jitters.push_back(jitter);
168                 }
169                 lastFrame = currFrame;
170                 (fpsInfo.timeStampQ).pop();
171             }
172             fpsConfig.fpsGb = fpsTmp;
173             (fpsInfo.timeStampQ).push(frameReadyTime);
174             fpsInfo.lastFrameReadyTime = lastFrame;
175         } else if (tFrameReadyTime > tLastReadyTime + 1) {
176             fpsConfig.jump = true;
177             fpsConfig.lastReadyTime = frameReadyTime;
178             while (!(fpsInfo.timeStampQ).empty()) {
179                 (fpsInfo.timeStampQ).pop();
180             }
181             (fpsInfo.timeStampQ).push(frameReadyTime);
182         }
183     }
184 }
185 
GetSurfaceFrame(std::string name,FpsConfig & fpsConfig)186 static FpsInfo GetSurfaceFrame(std::string name, FpsConfig &fpsConfig)
187 {
188     static std::map<std::string, FpsInfo> fpsMap;
189     if (fpsMap.count(name) == 0) {
190         FpsInfo tmp;
191         tmp.fps = 0;
192         tmp.preFps = 0;
193         fpsMap[name] = tmp;
194     }
195     FpsInfo &fpsInfo = fpsMap[name];
196     fpsInfo.fps = 0;
197     struct timeval tv;
198     gettimeofday(&tv, nullptr);
199     fpsInfo.currentFpsTime = tv.tv_sec * 1e3 + tv.tv_usec / 1e3;
200     std::string cmd = "hidumper -s 10 -a \"fps " + name + "\"";
201     std::string cmdExc = cmd;
202     FILE *fp = popen(cmdExc.c_str(), "r");
203     if (fp == nullptr) {
204         return fpsInfo;
205     }
206     static long long lastLineTime;
207     if (!(fpsInfo.timeStampQ).empty()) {
208         fpsConfig.lastReadyTime = (fpsInfo.timeStampQ).back();
209         lastLineTime = (fpsInfo.timeStampQ).back();
210     }
211     ProcessResult(fp, fpsConfig, fpsInfo);
212     pclose(fp);
213     const int maxZeroNum = 120;
214     const int minPrintLine = 5;
215     if (fpsConfig.zeroNum >= maxZeroNum) {
216         while (!(fpsInfo.timeStampQ.empty())) {
217             fpsInfo.timeStampQ.pop();
218         }
219         fpsInfo.fps = 0;
220         return fpsInfo;
221     }
222 
223     if (fpsConfig.cnt < minPrintLine) {
224         fpsInfo.fps = fpsInfo.preFps;
225         return fpsInfo;
226     }
227 
228     if (!fpsInfo.timeStampQ.empty() && fpsInfo.timeStampQ.back() == lastLineTime) {
229         fpsInfo.fps = 0;
230         return fpsInfo;
231     }
232 
233     if (fpsConfig.fpsGb > 0) {
234         fpsInfo.fps = fpsConfig.fpsGb;
235         fpsInfo.preFps = fpsConfig.fpsGb;
236         return fpsInfo;
237     } else if (fpsConfig.refresh && !fpsConfig.jump) {
238         fpsInfo.fps = fpsInfo.preFps;
239         return fpsInfo;
240     } else {
241         fpsInfo.fps = 0;
242         return fpsInfo;
243     }
244 }
245 
ReplaceString(std::string & res)246 static void ReplaceString(std::string &res)
247 {
248     std::string flagOne = "\r";
249     std::string flagTwo = "\n";
250     std::string::size_type ret = res.find(flagOne);
251     while (ret != res.npos) {
252         res.replace(ret, 1, "");
253         ret = res.find(flagOne);
254     }
255     ret = res.find(flagTwo);
256     while (ret != res.npos) {
257         res.replace(ret, 1, "");
258         ret = res.find(flagTwo);
259     }
260 }
261 
LoadCmd(const std::string & cmd,std::string & result)262 static bool LoadCmd(const std::string &cmd, std::string &result)
263 {
264     std::string cmdExc = cmd;
265     FILE *fd = popen(cmdExc.c_str(), "r");
266     if (fd == nullptr) {
267         return false;
268     }
269     char buf[1024] = {'\0'};
270     int ret = fread(buf, sizeof(buf), 1, fd);
271     if (ret >= 0) {
272         result = buf;
273     }
274     if (pclose(fd) == -1) {
275         std::cout << "" << std::endl;
276     }
277     ReplaceString(result);
278     return ret >= 0 ? true : false;
279 }
GetSurFace()280 static std::string GetSurFace()
281 {
282     std::string cmdResult;
283     std::string cmdString1 = "hidumper -s 10 -a sur";
284     std::string cmdString2 = "face | grep sur";
285     std::string cmdString3 = "face";
286     LoadCmd(cmdString1 + cmdString2 + cmdString3, cmdResult);
287     size_t position1 = cmdResult.find("[");
288     size_t position2 = cmdResult.find("]");
289     return cmdResult.substr(position1 + 1, position2 - position1 - 1);
290 }
main(int argc,char * argv[])291 int main(int argc, char *argv[])
292 {
293     if (argc < 2) {
294         printf("exec failed, require one param | example: GP_daemon_fps 10");
295         return 0;
296     }
297     int num = 1;
298     if (!strcmp(argv[1], "")) {
299         printf("the args of num must be not-null!\n");
300     } else {
301         num = atoi(argv[1]);
302         if (num < 0) {
303             printf("set num:%d not valid arg\n", num);
304         }
305         printf("set num:%d success\n", num);
306         FpsInfo gfpsInfo;
307         FpsInfo gfpsUniteInfo;
308         std::string layerName;
309         std::string tempLayerName;
310         struct timeval start;
311         struct timeval end;
312         std::string uniteLayer = "DisplayNode";
313         uniteLayer = GetSurFace();
314         unsigned long oneSec = 1000000;
315         std::string cmdResult;
316         for (int i = 0; i < num; i++) {
317             unsigned long runTime;
318             gettimeofday(&start, nullptr);
319             tempLayerName = GetLayer();
320             if (i == 0) {
321                 layerName = tempLayerName;
322                 LoadCmd("hidumper -s 10 -a \"fpsClear DisplayNode\"", cmdResult);
323                 LoadCmd("hidumper -s 10 -a \"fpsClear" + layerName + "\"", cmdResult);
324             } else {
325                 if (layerName.compare(tempLayerName) != 0) {
326                     layerName = tempLayerName;
327                     LoadCmd("hidumper -s 10 -a \"fpsClear" + layerName + "\"", cmdResult);
328                 }
329             }
330             FpsConfig fpsConfig;
331             FpsConfig fpsUniteConfig;
332             gfpsInfo = GetSurfaceFrame(layerName, fpsConfig);
333             gfpsUniteInfo = GetSurfaceFrame(uniteLayer, fpsUniteConfig);
334             if (gfpsUniteInfo.fps > gfpsInfo.fps)
335             {
336                 printf("fps:%d|%lld\n", gfpsUniteInfo.fps, gfpsUniteInfo.currentFpsTime);
337             } else {
338                 printf("fps:%d|%lld\n", gfpsInfo.fps, gfpsInfo.currentFpsTime);
339             }
340             fflush(stdout);
341             gettimeofday(&end, nullptr);
342             runTime = end.tv_sec * 1e6 - start.tv_sec * 1e6 + end.tv_usec - start.tv_usec;
343             if (runTime < oneSec) {
344                 usleep(oneSec - runTime);
345             }
346         }
347     }
348     printf("GP_daemon_fps exec finished!\n");
349     return 0;
350 }
351