• 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 <string>
20 #include <thread>
21 #include "include/sp_utils.h"
22 #include "include/ByTrace.h"
23 #include "include/Capture.h"
24 #include "include/FPS.h"
25 #include "include/sp_log.h"
26 namespace OHOS {
27 namespace SmartPerf {
ItemData()28 std::map<std::string, std::string> FPS::ItemData()
29 {
30     std::map<std::string, std::string> result;
31     FpsInfo fpsInfoResult;
32     if (surfaceViewName.length() > 0) {
33         fpsInfoResult = GetDiffLayersFpsInfo(surfaceViewName);
34     } else {
35         fpsInfoResult = GetFpsInfo();
36     }
37     result["fps"] = std::to_string(fpsInfoResult.fps);
38     LOGI("result.fps====: %s", std::to_string(fpsInfoResult.fps).c_str());
39     std::string jitterStr = "";
40     std::string split = "";
41     for (size_t i = 0; i < fpsInfoResult.jitters.size(); i++) {
42         if (i > 0) {
43             split = ";;";
44         }
45         jitterStr += split + std::to_string(fpsInfoResult.jitters[i]);
46     }
47     result["fpsJitters"] = jitterStr;
48     LOGI("result.jitters====: %s", jitterStr.c_str());
49     if (isCatchTrace > 0) {
50         ByTrace::GetInstance().CheckFpsJitters(fpsInfoResult.jitters, fpsInfoResult.fps);
51     }
52     if (isCapture > 0) {
53         Capture::GetInstance().TriggerGetCatch(SPUtils::GetCurTime());
54     }
55     return result;
56 }
57 
SetTraceCatch()58 void FPS::SetTraceCatch()
59 {
60     isCatchTrace = 1;
61 }
62 
SetCaptureOn()63 void FPS::SetCaptureOn()
64 {
65     isCapture = 1;
66 }
67 
SetPackageName(std::string pName)68 void FPS::SetPackageName(std::string pName)
69 {
70     pkgName = std::move(pName);
71 }
SetLayerName(std::string sName)72 void FPS::SetLayerName(std::string sName)
73 {
74     surfaceViewName = std::move(sName);
75 }
GetDiffLayersFpsInfo(std::string sName)76 FpsInfo FPS::GetDiffLayersFpsInfo(std::string sName)
77 {
78     FpsInfo surfaceFramefpsInfo = GetSurfaceFrame(sName);
79     return surfaceFramefpsInfo;
80 }
GetSurface()81 std::string FPS::GetSurface()
82 {
83     std::string cmdResult;
84     std::string cmdString1 = "hidumper -s 10 -a sur";
85     std::string cmdString2 = "face | grep sur";
86     std::string cmdString3 = "face";
87     SPUtils::LoadCmd(cmdString1 + cmdString2 + cmdString3, cmdResult);
88     size_t position1 = cmdResult.find("[");
89     size_t position2 = cmdResult.find("]");
90     LOGI("cmdResult==: %s", (cmdResult.substr(position1 + 1, position2 - position1 - 1)).c_str());
91     return cmdResult.substr(position1 + 1, position2 - position1 - 1);
92 }
PrintFpsInfo(FpsInfo & fpsInfo,const std::string tag,const std::string type)93 static void PrintFpsInfo(FpsInfo &fpsInfo, const std::string tag, const std::string type)
94 {
95     LOGI("Print fps: %s", std::to_string(fpsInfo.fps).c_str());
96     LOGI("Print tag: %s", tag.c_str());
97     LOGI("Print type: %s", type.c_str());
98     std::string jitterStr = "";
99     std::string split = "";
100     for (size_t i = 0; i < fpsInfo.jitters.size(); i++) {
101         if (i > 0) {
102             split = ";;";
103         }
104         jitterStr += split + std::to_string(fpsInfo.jitters[i]);
105     }
106     LOGI("Print jitterStr: %s", jitterStr.c_str());
107 }
CutLayerName(std::string layerName)108 std::string FPS::CutLayerName(std::string layerName)
109 {
110     std::string subLayerName;
111     size_t twenty = 20;
112     if (layerName.size() > twenty) {
113         subLayerName = layerName.substr(0, twenty);
114     } else {
115         subLayerName = layerName;
116     }
117     return subLayerName;
118 }
119 
GetFpsInfoMax()120 FpsInfo FPS::GetFpsInfoMax()
121 {
122     int fpsValue = 0;
123     if (fpsInfo.fps > uniteFpsInfo.fps) {
124         fpsInfoMax = fpsInfo;
125     } else {
126         fpsInfoMax = uniteFpsInfo;
127     }
128     if (fpsInfoMax.fps < fpsValue) {
129         fpsInfoMax.fps = fpsValue;
130     }
131     if (fpsInfoMax == prevFlagFpsInfo) {
132         LOGI("fpsInfoMax == prevFlagFpsInfo");
133         if (cntFpsInfo == lastFlagFpsInfo) {
134             LOGI("cntFpsInfo == lastFlagFpsInfo");
135             fpsInfoMax.fps = 0;
136             fpsInfoMax.Clear();
137             return fpsInfoMax;
138         } else {
139             LOGI("cntFpsInfo != lastFlagFpsInfo");
140             if ((cntFpsInfo.jitters.size() > 0 && lastFlagFpsInfo.jitters.size() > 0) &&
141                 cntFpsInfo.jitters[0] == lastFlagFpsInfo.jitters[0]) {
142                 LOGI("cntFpsInfo.jitters.size: %s", std::to_string(cntFpsInfo.jitters.size()).c_str());
143                 LOGI("lastFlagFpsInfo.jitters.size: %s", std::to_string(lastFlagFpsInfo.jitters.size()).c_str());
144                 LOGI("cntFpsInfo.jitters[0]: %s", std::to_string(cntFpsInfo.jitters[0]).c_str());
145                 LOGI("lastFlagFpsInfo.jitters[0]: %s", std::to_string(lastFlagFpsInfo.jitters[0]).c_str());
146                 cntFpsInfo.fps = 0;
147                 cntFpsInfo.Clear();
148             } else {
149                 LOGI("6666666666666666666");
150                 lastFlagFpsInfo = cntFpsInfo;
151             }
152             return cntFpsInfo;
153         }
154     } else {
155         LOGI("fpsInfoMax != prevFlagFpsInfo");
156         if ((fpsInfoMax.jitters.size() > 0 && lastFlagFpsInfo.jitters.size() > 0) &&
157             fpsInfoMax.jitters[0] == lastFlagFpsInfo.jitters[0]) {
158             LOGI("fpsInfoMax == lastFlagFpsInfo");
159             lastFlagFpsInfo = cntFpsInfo;
160             return cntFpsInfo;
161         } else {
162             LOGI("fpsInfoMax != lastFlagFpsInfo");
163             prevFlagFpsInfo = fpsInfoMax;
164             return fpsInfoMax;
165         }
166     }
167 }
168 
GetFpsInfo()169 FpsInfo FPS::GetFpsInfo()
170 {
171     fpsInfoMax.fps = 0;
172     if (pkgName.empty()) {
173         return fpsInfoMax;
174     }
175     std::vector<std::string> sps;
176     SPUtils::StrSplit(this->pkgName, ".", sps);
177     std::string layerName = std::string(sps[sps.size() - 1].c_str());
178     LOGI("layerName===: %s", layerName.c_str());
179     std::string uniteLayer = "DisplayNode";
180     uniteLayer = GetSurface();
181     LOGI("uniteLayer===: %s", uniteLayer.c_str());
182     std::string line = GetLayer(layerName);
183     LOGI("line===: %s", line.c_str());
184     std::vector<std::string> params;
185     SPUtils::StrSplit(line, ":", params);
186     std::string pkgZOrd = params[1];
187     LOGI("pkgZOrd===: %s", pkgZOrd.c_str());
188     std::string zOrd = "-1";
189     std::string focusSurface = params[0];
190     LOGI("focusSurface===: %s", focusSurface.c_str());
191     std::string subStrLayerName = CutLayerName(layerName);
192     LOGI("subStrLayerName===: %s", subStrLayerName.c_str());
193     if ((focusSurface.find(subStrLayerName) != std::string::npos) && (strcmp(pkgZOrd.c_str(), zOrd.c_str()) != 0)) {
194         uniteFpsInfo = GetSurfaceFrame(uniteLayer);
195         PrintFpsInfo(uniteFpsInfo, uniteLayer, "one");
196     }
197     fpsInfo = GetSurfaceFrame(focusSurface);
198     PrintFpsInfo(fpsInfo, focusSurface, "two");
199     return GetFpsInfoMax();
200 }
GetFpsInfoResult(FpsInfo & fpsInfo,long long & lastLineTime)201 FpsInfo FPS::GetFpsInfoResult(FpsInfo &fpsInfo, long long &lastLineTime)
202 {
203     const int maxZeroNum = 266;
204     if (zeroNum >= maxZeroNum) {
205         LOGI("zeroNum====: %s", std::to_string(zeroNum).c_str());
206         while (!(fpsInfo.timeStampQ.empty())) {
207             fpsInfo.timeStampQ.pop();
208         }
209         fpsInfo.fps = 0;
210         fpsInfo.jitters.clear();
211         LOGI("fpsInfo.fps0: %s", std::to_string(fpsInfo.fps).c_str());
212         return fpsInfo;
213     }
214     const int minPrintLine = 5;
215     if (cnt < minPrintLine) {
216         fpsInfo.fps = fpsInfo.preFps;
217         LOGI("fpsInfo.fps1: %s", std::to_string(fpsInfo.fps).c_str());
218         return fpsInfo;
219     }
220     if (!fpsInfo.timeStampQ.empty() && fpsInfo.timeStampQ.back() == lastLineTime) {
221         fpsInfo.fps = fpsGb;
222         if (fpsGb == 0) {
223             fpsInfo.jitters.clear();
224         }
225         LOGI("fpsInfo.fps2: %s", std::to_string(fpsInfo.fps).c_str());
226         LOGI("lastLineTime: %s", std::to_string(lastLineTime).c_str());
227         return fpsInfo;
228     }
229     if (fpsGb > 0) {
230         fpsInfo.fps = fpsGb;
231         fpsInfo.preFps = fpsGb;
232         LOGI("fpsInfo.fps3: %s", std::to_string(fpsInfo.fps).c_str());
233         LOGI("fpsInfo.preFps3: %s", std::to_string(fpsInfo.preFps).c_str());
234         return fpsInfo;
235     } else if (refresh && !jump) {
236         fpsInfo.fps = fpsInfo.preFps;
237         LOGI("fpsInfo.fps4: %s", std::to_string(fpsInfo.fps).c_str());
238         return fpsInfo;
239     } else {
240         fpsInfo.fps = 0;
241         fpsInfo.jitters.clear();
242         LOGI("fpsInfo.fps5: %s", std::to_string(fpsInfo.fps).c_str());
243         return fpsInfo;
244     }
245 }
246 
GetLastFpsInfo(FpsInfo & fpsInfo)247 void FPS::GetLastFpsInfo(FpsInfo &fpsInfo)
248 {
249     int total = 266;
250     if (cnt == total && fpsGb != 0) {
251         LOGI("cnt == total && fpsGb != 0");
252         lastReadyTime = frameReadyTime;
253         int fpsTmp = 0;
254         cntFpsInfo.jitters.clear();
255         while (!(fpsInfo.timeStampQ).empty()) {
256             fpsTmp++;
257             long long currFrame = (fpsInfo.timeStampQ.front());
258             if (lastFrame != -1) {
259                 long long jitter = currFrame - lastFrame;
260                 cntFpsInfo.jitters.push_back(jitter);
261             } else {
262                 long long jitter = currFrame - currFrame / mod * mod;
263                 cntFpsInfo.jitters.push_back(jitter);
264             }
265             lastFrame = currFrame;
266             (fpsInfo.timeStampQ).pop();
267         }
268         cntFpsInfo.fps = fpsTmp;
269         LOGI("cntFpsInfo.fps====: %s", std::to_string(cntFpsInfo.fps).c_str());
270     }
271 }
272 
GetPrevFpsInfo(FpsInfo & fpsInfo)273 void FPS::GetPrevFpsInfo(FpsInfo &fpsInfo)
274 {
275     refresh = true;
276     long long tFrameReadyTime = frameReadyTime / mod;
277     long long tLastReadyTime = lastReadyTime / mod;
278     lastFrame = -1;
279     if (tFrameReadyTime == tLastReadyTime) {
280         (fpsInfo.timeStampQ).push(frameReadyTime);
281     } else if (tFrameReadyTime == tLastReadyTime + 1) {
282         jump = true;
283         lastReadyTime = frameReadyTime;
284         int fpsTmp = 0;
285         fpsInfo.jitters.clear();
286         while (!(fpsInfo.timeStampQ).empty()) {
287             fpsTmp++;
288             long long currFrame = (fpsInfo.timeStampQ.front());
289             if (lastFrame != -1) {
290                 long long jitter = currFrame - lastFrame;
291                 fpsInfo.jitters.push_back(jitter);
292             } else {
293                 long long jitter = currFrame - currFrame / mod * mod;
294                 fpsInfo.jitters.push_back(jitter);
295             }
296             lastFrame = currFrame;
297             (fpsInfo.timeStampQ).pop();
298         }
299         fpsGb = fpsTmp;
300         LOGI("fpsGb====: %s", std::to_string(fpsGb).c_str());
301         (fpsInfo.timeStampQ).push(frameReadyTime);
302         fpsInfo.lastFrameReadyTime = lastFrame;
303     } else if (tFrameReadyTime > tLastReadyTime + 1) {
304         jump = true;
305         lastReadyTime = frameReadyTime;
306         while (!(fpsInfo.timeStampQ).empty()) {
307             (fpsInfo.timeStampQ).pop();
308         }
309         (fpsInfo.timeStampQ).push(frameReadyTime);
310     }
311 }
InitParams(FpsInfo & fpsInfo,long long & lastLineTime)312 void FPS::InitParams(FpsInfo &fpsInfo, long long &lastLineTime)
313 {
314     lastReadyTime = -1;
315     fpsGb = 0;
316     if (!(fpsInfo.timeStampQ).empty()) {
317         lastReadyTime = (fpsInfo.timeStampQ).back();
318         lastLineTime = (fpsInfo.timeStampQ).back();
319     }
320     jump = false;
321     refresh = false;
322     cnt = 0;
323     zeroNum = 0;
324 }
325 
GetSurfaceFrame(std::string name)326 FpsInfo FPS::GetSurfaceFrame(std::string name)
327 {
328     if (name == "") {
329         return FpsInfo();
330     }
331     static std::map<std::string, FpsInfo> fpsMap;
332     if (fpsMap.count(name) == 0) {
333         FpsInfo tmp;
334         tmp.fps = 0;
335         tmp.preFps = 0;
336         fpsMap[name] = tmp;
337     }
338     fpsInfo = fpsMap[name];
339     fpsInfo.fps = 0;
340     FILE *fp;
341     static char tmp[1024];
342     std::string cmd = "hidumper -s 10 -a \"fps " + name + "\"";
343     LOGI("cmd=====: %s", cmd.c_str());
344     fp = popen(cmd.c_str(), "r");
345     if (fp == nullptr) {
346         return fpsInfo;
347     }
348     static long long lastLineTime;
349     InitParams(fpsInfo, lastLineTime);
350     LOGI("dump time: start!");
351     while (fgets(tmp, sizeof(tmp), fp) != nullptr) {
352         std::string str(tmp);
353         LOGD("dump time: %s", str.c_str());
354         frameReadyTime = 0;
355         std::stringstream sstream;
356         sstream << tmp;
357         sstream >> frameReadyTime;
358         cnt++;
359         if (frameReadyTime == 0) {
360             zeroNum++;
361             continue;
362         }
363         if (lastReadyTime >= frameReadyTime) {
364             lastReadyTime = -1;
365             continue;
366         }
367         GetPrevFpsInfo(fpsInfo);
368         GetLastFpsInfo(fpsInfo);
369     }
370     pclose(fp);
371     return GetFpsInfoResult(fpsInfo, lastLineTime);
372 }
373 
GetLayer(std::string pkgSurface)374 std::string FPS::GetLayer(std::string pkgSurface)
375 {
376     std::vector<DumpEntity> dumpEntityList;
377     std::string curFocusId = "-1";
378     const std::string cmd = "hidumper -s WindowManagerService -a -a";
379     FILE *fd = popen(cmd.c_str(), "r");
380     if (fd != nullptr) {
381         int lineNum = 0;
382         char buf[1024] = {'\0'};
383         const int paramFourteen = 14;
384         const int paramTwentyFour = 24;
385         const int paramThree = 3;
386         const int windowNameIndex = 0;
387         const int windowIdIndex = 3;
388         const int focusNameIndex = 2;
389         while ((fgets(buf, sizeof(buf), fd)) != nullptr) {
390             std::string line = buf;
391             LOGE("hidumperline: %s", line.c_str());
392             if (line[0] == '-' || line[0] == ' ') {
393                 continue;
394             }
395             std::vector<std::string> params;
396             SPUtils::StrSplit(line, " ", params);
397             if (params[windowNameIndex].find("WindowName") != std::string::npos &&
398                 params[windowIdIndex].find("WinId") != std::string::npos) {
399                 continue;
400             }
401             if (params.size() > paramFourteen) {
402                 DumpEntity dumpEntity { params[0], params[1], params[2], params[3], params[7]};
403                 dumpEntityList.push_back(dumpEntity);
404             }
405             if (params.size() == paramFourteen || params.size() == paramTwentyFour) {
406                 DumpEntity dumpEntity { params[0], params[2], params[2], params[3], params[6]};
407                 dumpEntityList.push_back(dumpEntity);
408             }
409             if (params.size() == paramThree) {
410                 curFocusId = params[focusNameIndex];
411                 break;
412             }
413             lineNum++;
414         }
415         pclose(fd);
416     }
417 
418     std::string focusWindowName = "NA";
419     std::string pkgZOrd = "-1";
420     std::string spSurfacePrefix = "sp_";
421     std::string floatWindow = "floatWindow";
422     int curId = std::stoi(curFocusId);
423     LOGE("getLayerCurId====: %s", std::to_string(curId).c_str());
424     for (size_t i = 0; i < dumpEntityList.size(); i++) {
425         DumpEntity dumpItem = dumpEntityList[i];
426         int curWinId = std::stoi(dumpItem.windId);
427         if (curId == curWinId) {
428             LOGE("curId == curWinId");
429             if ((dumpItem.windowName.find(spSurfacePrefix) != std::string::npos ||
430                 dumpItem.windowName.find(floatWindow) != std::string::npos) && dumpItem.zOrd != "-1") {
431                 continue;
432             }
433             focusWindowName = dumpItem.windowName;
434             LOGE("focusWindowName: %s", focusWindowName.c_str());
435             LOGE("dumpItem.windowName: %s", dumpItem.windowName.c_str());
436         }
437         if (dumpItem.windowName.find(pkgSurface) != std::string::npos && dumpItem.zOrd != "-1") {
438             focusWindowName = dumpItem.windowName;
439             pkgZOrd = dumpItem.zOrd;
440             LOGE("pkgZOrd: %s", pkgZOrd.c_str());
441             LOGE("dumpItem.zOrd: %s", dumpItem.zOrd.c_str());
442             LOGE("focusWindowName2: %s", focusWindowName.c_str());
443             LOGE("dumpItem.windowName2: %s", dumpItem.windowName.c_str());
444         }
445     }
446     return focusWindowName + ":" + pkgZOrd;
447 }
448 }
449 }
450