106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#include <cstdio> 1606f6ba60Sopenharmony_ci#include <algorithm> 1706f6ba60Sopenharmony_ci#include <iostream> 1806f6ba60Sopenharmony_ci#include <sstream> 1906f6ba60Sopenharmony_ci#include <queue> 2006f6ba60Sopenharmony_ci#include <vector> 2106f6ba60Sopenharmony_ci#include <map> 2206f6ba60Sopenharmony_ci#include <string> 2306f6ba60Sopenharmony_ci#include <ctime> 2406f6ba60Sopenharmony_ci#include <thread> 2506f6ba60Sopenharmony_ci#include <unistd.h> 2606f6ba60Sopenharmony_ci#include <sys/time.h> 2706f6ba60Sopenharmony_ci#include "include/profiler_fps.h" 2806f6ba60Sopenharmony_ci#include "include/sp_log.h" 2906f6ba60Sopenharmony_ci#include "include/sp_utils.h" 3006f6ba60Sopenharmony_ci#include "include/ByTrace.h" 3106f6ba60Sopenharmony_ci#include "include/startup_delay.h" 3206f6ba60Sopenharmony_ci#include "include/common.h" 3306f6ba60Sopenharmony_ci 3406f6ba60Sopenharmony_cinamespace OHOS { 3506f6ba60Sopenharmony_cinamespace SmartPerf { 3606f6ba60Sopenharmony_cistd::map<std::string, std::string> ProfilerFPS::ItemData() 3706f6ba60Sopenharmony_ci{ 3806f6ba60Sopenharmony_ci std::map<std::string, std::string> result; 3906f6ba60Sopenharmony_ci FpsInfoProfiler finalResult; 4006f6ba60Sopenharmony_ci if (isGameLayer == "1") { 4106f6ba60Sopenharmony_ci std::string gameLayerName = GetGameLayer(); 4206f6ba60Sopenharmony_ci LOGI("ProfilerFPS::gameLayerName: (%s)", gameLayerName.c_str()); 4306f6ba60Sopenharmony_ci if (!gameLayerName.empty()) { 4406f6ba60Sopenharmony_ci finalResult = selfRerderLayers(gameLayerName); 4506f6ba60Sopenharmony_ci } 4606f6ba60Sopenharmony_ci } else { 4706f6ba60Sopenharmony_ci finalResult = GetFpsInfo(); 4806f6ba60Sopenharmony_ci } 4906f6ba60Sopenharmony_ci lastFpsInfoResult = finalResult; 5006f6ba60Sopenharmony_ci if (processFlag) { 5106f6ba60Sopenharmony_ci result["fps"] = "NA"; 5206f6ba60Sopenharmony_ci result["fpsJitters"] = "NA"; 5306f6ba60Sopenharmony_ci } else { 5406f6ba60Sopenharmony_ci int fullFrame = 120; 5506f6ba60Sopenharmony_ci if (finalResult.fps > fullFrame) { 5606f6ba60Sopenharmony_ci finalResult.fps = fullFrame; 5706f6ba60Sopenharmony_ci } 5806f6ba60Sopenharmony_ci result["fps"] = std::to_string(finalResult.fps); 5906f6ba60Sopenharmony_ci LOGI("ProfilerFPS.result.fps: %s", std::to_string(finalResult.fps).c_str()); 6006f6ba60Sopenharmony_ci LOGI("ProfilerFPS.result.curTime: %s", std::to_string(finalResult.curTime).c_str()); 6106f6ba60Sopenharmony_ci std::string jitterStr = ""; 6206f6ba60Sopenharmony_ci std::string split = ""; 6306f6ba60Sopenharmony_ci for (size_t i = 0; i < finalResult.jitters.size(); i++) { 6406f6ba60Sopenharmony_ci if (i > 0) { 6506f6ba60Sopenharmony_ci split = ";;"; 6606f6ba60Sopenharmony_ci } 6706f6ba60Sopenharmony_ci jitterStr += split + std::to_string(finalResult.jitters[i]); 6806f6ba60Sopenharmony_ci } 6906f6ba60Sopenharmony_ci result["fpsJitters"] = jitterStr; 7006f6ba60Sopenharmony_ci LOGI("ProfilerFPS.result.jitters: %s", jitterStr.c_str()); 7106f6ba60Sopenharmony_ci if (isCatchTrace > 0) { 7206f6ba60Sopenharmony_ci ByTrace::GetInstance().CheckFpsJitters(finalResult.jitters, finalResult.fps); 7306f6ba60Sopenharmony_ci } 7406f6ba60Sopenharmony_ci } 7506f6ba60Sopenharmony_ci return result; 7606f6ba60Sopenharmony_ci} 7706f6ba60Sopenharmony_ci 7806f6ba60Sopenharmony_civoid ProfilerFPS::SetTraceCatch() 7906f6ba60Sopenharmony_ci{ 8006f6ba60Sopenharmony_ci isCatchTrace = 1; 8106f6ba60Sopenharmony_ci} 8206f6ba60Sopenharmony_ci 8306f6ba60Sopenharmony_civoid ProfilerFPS::SetPackageName(std::string pName) 8406f6ba60Sopenharmony_ci{ 8506f6ba60Sopenharmony_ci pkgName = std::move(pName); 8606f6ba60Sopenharmony_ci} 8706f6ba60Sopenharmony_ci 8806f6ba60Sopenharmony_civoid ProfilerFPS::SetProcessId(const std::string &pid) 8906f6ba60Sopenharmony_ci{ 9006f6ba60Sopenharmony_ci processId = pid; 9106f6ba60Sopenharmony_ci} 9206f6ba60Sopenharmony_ci 9306f6ba60Sopenharmony_civoid ProfilerFPS::GetResultFPS(int sectionsNum) 9406f6ba60Sopenharmony_ci{ 9506f6ba60Sopenharmony_ci struct timeval start; 9606f6ba60Sopenharmony_ci struct timeval end; 9706f6ba60Sopenharmony_ci gettimeofday(&start, nullptr); 9806f6ba60Sopenharmony_ci FpsInfoProfiler fpsInfoResult; 9906f6ba60Sopenharmony_ci unsigned long runTime; 10006f6ba60Sopenharmony_ci fpsInfoResult = GetFpsInfo(); 10106f6ba60Sopenharmony_ci if (fpsInfoResult.fps == 0) { 10206f6ba60Sopenharmony_ci if (lastCurrTime == 0) { 10306f6ba60Sopenharmony_ci long long currTime = (fpsInfoResult.currTimeDump / msClear) * msClear + fpsInfoResult.currTimeDiff; 10406f6ba60Sopenharmony_ci lastCurrTime = currTime / oneSec; 10506f6ba60Sopenharmony_ci printf("fps:%d|%lld\n", fpsInfoResult.fps, currTime / oneSec); 10606f6ba60Sopenharmony_ci } else { 10706f6ba60Sopenharmony_ci printf("fps:%d|%lld\n", fpsInfoResult.fps, lastCurrTime + oneThousand); 10806f6ba60Sopenharmony_ci lastCurrTime = lastCurrTime + oneThousand; 10906f6ba60Sopenharmony_ci } 11006f6ba60Sopenharmony_ci } else { 11106f6ba60Sopenharmony_ci long long currTime = (fpsInfoResult.currTimeStamps[0] / msClear) * msClear + fpsInfoResult.currTimeDiff; 11206f6ba60Sopenharmony_ci lastCurrTime = currTime / oneSec; 11306f6ba60Sopenharmony_ci printf("fps:%d|%lld\n", fpsInfoResult.fps, lastCurrTime); 11406f6ba60Sopenharmony_ci } 11506f6ba60Sopenharmony_ci lastFpsInfoResult = fpsInfoResult; 11606f6ba60Sopenharmony_ci if (sectionsNum != 0 && fpsInfoResult.fps != 0) { 11706f6ba60Sopenharmony_ci GetSectionsFps(fpsInfoResult, sectionsNum); 11806f6ba60Sopenharmony_ci } 11906f6ba60Sopenharmony_ci time_t now = time(nullptr); 12006f6ba60Sopenharmony_ci if (now == -1) { 12106f6ba60Sopenharmony_ci LOGI("Failed to get current time."); 12206f6ba60Sopenharmony_ci return; 12306f6ba60Sopenharmony_ci } 12406f6ba60Sopenharmony_ci char *dt = ctime(&now); 12506f6ba60Sopenharmony_ci LOGI("printf time is: %s", dt); 12606f6ba60Sopenharmony_ci fflush(stdout); 12706f6ba60Sopenharmony_ci gettimeofday(&end, nullptr); 12806f6ba60Sopenharmony_ci runTime = end.tv_sec * 1e6 - start.tv_sec * 1e6 + end.tv_usec - start.tv_usec; 12906f6ba60Sopenharmony_ci LOGI("printf time is runTime: %s", std::to_string(runTime).c_str()); 13006f6ba60Sopenharmony_ci if (runTime < sleepTime) { 13106f6ba60Sopenharmony_ci usleep(sleepTime - runTime); 13206f6ba60Sopenharmony_ci } 13306f6ba60Sopenharmony_ci OHOS::SmartPerf::SPUtils::GetCurrentTime(ten, lastFpsInfoResult.curTime); 13406f6ba60Sopenharmony_ci} 13506f6ba60Sopenharmony_ci 13606f6ba60Sopenharmony_civoid ProfilerFPS::GetTimeDiff() 13706f6ba60Sopenharmony_ci{ 13806f6ba60Sopenharmony_ci long long clockRealTime = 0; 13906f6ba60Sopenharmony_ci long long clockMonotonicRaw = 0; 14006f6ba60Sopenharmony_ci int two = 2; 14106f6ba60Sopenharmony_ci std::string strRealTime; 14206f6ba60Sopenharmony_ci const std::string cmd = CMD_COMMAND_MAP.at(CmdCommand::TIMESTAMPS); 14306f6ba60Sopenharmony_ci FILE *fd = popen(cmd.c_str(), "r"); 14406f6ba60Sopenharmony_ci if (fd == nullptr) { 14506f6ba60Sopenharmony_ci return; 14606f6ba60Sopenharmony_ci } 14706f6ba60Sopenharmony_ci char buf[1024] = {'\0'}; 14806f6ba60Sopenharmony_ci while ((fgets(buf, sizeof(buf), fd)) != nullptr) { 14906f6ba60Sopenharmony_ci std::string line = buf; 15006f6ba60Sopenharmony_ci std::vector<std::string> params; 15106f6ba60Sopenharmony_ci SPUtils::StrSplit(line, " ", params); 15206f6ba60Sopenharmony_ci if (params[0].find("CLOCK_REALTIME") != std::string::npos && clockRealTime == 0) { 15306f6ba60Sopenharmony_ci strRealTime = params[two]; 15406f6ba60Sopenharmony_ci strRealTime.erase(strRealTime.find('.'), 1); 15506f6ba60Sopenharmony_ci clockRealTime = std::stoll(strRealTime); 15606f6ba60Sopenharmony_ci currRealTime = clockRealTime; 15706f6ba60Sopenharmony_ci } else if (params[0].find("CLOCK_MONOTONIC_RAW") != std::string::npos && clockMonotonicRaw == 0) { 15806f6ba60Sopenharmony_ci strRealTime = params[two]; 15906f6ba60Sopenharmony_ci strRealTime.erase(strRealTime.find('.'), 1); 16006f6ba60Sopenharmony_ci clockMonotonicRaw = std::stoll(strRealTime); 16106f6ba60Sopenharmony_ci } 16206f6ba60Sopenharmony_ci } 16306f6ba60Sopenharmony_ci pclose(fd); 16406f6ba60Sopenharmony_ci fpsInfo.currTimeDiff = clockRealTime - clockMonotonicRaw; 16506f6ba60Sopenharmony_ci} 16606f6ba60Sopenharmony_ci 16706f6ba60Sopenharmony_civoid ProfilerFPS::GetSectionsPrint(int printCount, long long msStartTime, int numb, long long harTime) const 16806f6ba60Sopenharmony_ci{ 16906f6ba60Sopenharmony_ci if (printCount < numb) { 17006f6ba60Sopenharmony_ci for (int i = 0; i < numb - printCount; i++) { 17106f6ba60Sopenharmony_ci msStartTime += harTime; 17206f6ba60Sopenharmony_ci printf("sectionsFps:%d|%lld\n", 0, msStartTime); 17306f6ba60Sopenharmony_ci } 17406f6ba60Sopenharmony_ci } 17506f6ba60Sopenharmony_ci} 17606f6ba60Sopenharmony_ci 17706f6ba60Sopenharmony_civoid ProfilerFPS::PrintSections(int msCount, long long currTimeLast, 17806f6ba60Sopenharmony_ci long long currTimeStart, long long currLastTime) const 17906f6ba60Sopenharmony_ci{ 18006f6ba60Sopenharmony_ci int conversionFps = 1000000; 18106f6ba60Sopenharmony_ci int conversionTime = 1000; 18206f6ba60Sopenharmony_ci long long times = 120; 18306f6ba60Sopenharmony_ci int fpsNums = 0; 18406f6ba60Sopenharmony_ci if (msCount == 0) { 18506f6ba60Sopenharmony_ci fpsNums = 0; 18606f6ba60Sopenharmony_ci } else { 18706f6ba60Sopenharmony_ci fpsNums = msCount - 1; 18806f6ba60Sopenharmony_ci } 18906f6ba60Sopenharmony_ci double timeN = (currTimeLast - currTimeStart) * 1.0 / conversionTime; 19006f6ba60Sopenharmony_ci if (timeN == 0) { 19106f6ba60Sopenharmony_ci printf("sectionsFps:%d|%lld\n", 0, currLastTime); 19206f6ba60Sopenharmony_ci return; 19306f6ba60Sopenharmony_ci } 19406f6ba60Sopenharmony_ci double fpsSections = (fpsNums * conversionFps) / timeN; 19506f6ba60Sopenharmony_ci int fpsSectionsInt = round(fpsSections); 19606f6ba60Sopenharmony_ci if (fpsSectionsInt > static_cast<int>(times)) { 19706f6ba60Sopenharmony_ci fpsSectionsInt = static_cast<int>(times); 19806f6ba60Sopenharmony_ci } 19906f6ba60Sopenharmony_ci printf("sectionsFps:%d|%lld\n", fpsSectionsInt, currLastTime); 20006f6ba60Sopenharmony_ci} 20106f6ba60Sopenharmony_ci 20206f6ba60Sopenharmony_civoid ProfilerFPS::GetSectionsFps(FpsInfoProfiler &fpsInfoResult, int nums) const 20306f6ba60Sopenharmony_ci{ 20406f6ba60Sopenharmony_ci int msCount = 0; 20506f6ba60Sopenharmony_ci long long msJiange = 0; 20606f6ba60Sopenharmony_ci if (nums != 0) { 20706f6ba60Sopenharmony_ci msJiange = msClear / nums; 20806f6ba60Sopenharmony_ci } 20906f6ba60Sopenharmony_ci long long msStartTime = (fpsInfoResult.currTimeStamps[0] / msClear) * msClear + msJiange; 21006f6ba60Sopenharmony_ci long long currLastTime = lastCurrTime; 21106f6ba60Sopenharmony_ci long long harTime = msJiange / 1000000; 21206f6ba60Sopenharmony_ci int printCount = 0; 21306f6ba60Sopenharmony_ci long long currTimeStart = 0; 21406f6ba60Sopenharmony_ci long long currTimeLast = 0; 21506f6ba60Sopenharmony_ci for (size_t i = 0; i < fpsInfoResult.currTimeStamps.size(); i++) { 21606f6ba60Sopenharmony_ci long long currTime = fpsInfoResult.currTimeStamps[i]; 21706f6ba60Sopenharmony_ci if (currTime <= msStartTime) { 21806f6ba60Sopenharmony_ci if (msCount == 0) { 21906f6ba60Sopenharmony_ci currTimeStart = currTime; 22006f6ba60Sopenharmony_ci } 22106f6ba60Sopenharmony_ci currTimeLast = currTime; 22206f6ba60Sopenharmony_ci msCount++; 22306f6ba60Sopenharmony_ci } else { 22406f6ba60Sopenharmony_ci while (currTime > msStartTime) { 22506f6ba60Sopenharmony_ci PrintSections(msCount, currTimeLast, currTimeStart, currLastTime); 22606f6ba60Sopenharmony_ci printCount++; 22706f6ba60Sopenharmony_ci msCount = 1; 22806f6ba60Sopenharmony_ci msStartTime += msJiange; 22906f6ba60Sopenharmony_ci currLastTime += harTime; 23006f6ba60Sopenharmony_ci currTimeLast = currTime; 23106f6ba60Sopenharmony_ci currTimeStart = currTime; 23206f6ba60Sopenharmony_ci } 23306f6ba60Sopenharmony_ci } 23406f6ba60Sopenharmony_ci if (i == (static_cast<size_t>(fpsInfoResult.currTimeStamps.size()) - 1)) { 23506f6ba60Sopenharmony_ci PrintSections(msCount, currTimeLast, currTimeStart, currLastTime); 23606f6ba60Sopenharmony_ci currTimeLast = currTime; 23706f6ba60Sopenharmony_ci printCount++; 23806f6ba60Sopenharmony_ci GetSectionsPrint(printCount, currLastTime, nums, harTime); 23906f6ba60Sopenharmony_ci } 24006f6ba60Sopenharmony_ci } 24106f6ba60Sopenharmony_ci} 24206f6ba60Sopenharmony_ci 24306f6ba60Sopenharmony_civoid ProfilerFPS::GetFPS(std::vector<std::string> v) 24406f6ba60Sopenharmony_ci{ 24506f6ba60Sopenharmony_ci if (v[number] == "") { 24606f6ba60Sopenharmony_ci printf("the args of num must be not-null!\n"); 24706f6ba60Sopenharmony_ci } else { 24806f6ba60Sopenharmony_ci this->num = atoi(v[number].c_str()); 24906f6ba60Sopenharmony_ci if (this->num < 0) { 25006f6ba60Sopenharmony_ci printf("set num:%d not valid arg\n", this->num); 25106f6ba60Sopenharmony_ci } 25206f6ba60Sopenharmony_ci printf("set num:%d success\n", this->num); 25306f6ba60Sopenharmony_ci int sectionsNum = (static_cast<int>(v.size()) >= four) ? atoi(v[four].c_str()) : 0; 25406f6ba60Sopenharmony_ci if (sectionsNum > ten) { 25506f6ba60Sopenharmony_ci printf("set sectionsNum:%d not valid arg \n", sectionsNum); 25606f6ba60Sopenharmony_ci } else { 25706f6ba60Sopenharmony_ci for (int i = 0; i < this->num; i++) { 25806f6ba60Sopenharmony_ci GetResultFPS(sectionsNum); 25906f6ba60Sopenharmony_ci } 26006f6ba60Sopenharmony_ci } 26106f6ba60Sopenharmony_ci } 26206f6ba60Sopenharmony_ci printf("SP_daemon exec finished!\n"); 26306f6ba60Sopenharmony_ci} 26406f6ba60Sopenharmony_ci 26506f6ba60Sopenharmony_cistd::string ProfilerFPS::GetSurface() 26606f6ba60Sopenharmony_ci{ 26706f6ba60Sopenharmony_ci std::string cmdResult; 26806f6ba60Sopenharmony_ci std::string dumperSurface = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SURFACE); 26906f6ba60Sopenharmony_ci SPUtils::LoadCmd(dumperSurface, cmdResult); 27006f6ba60Sopenharmony_ci size_t positionLeft = cmdResult.find("["); 27106f6ba60Sopenharmony_ci size_t positionRight = cmdResult.find("]"); 27206f6ba60Sopenharmony_ci size_t positionNum = 1; 27306f6ba60Sopenharmony_ci return cmdResult.substr(positionLeft + positionNum, positionRight - positionLeft - positionNum); 27406f6ba60Sopenharmony_ci} 27506f6ba60Sopenharmony_ci 27606f6ba60Sopenharmony_ciFpsInfoProfiler ProfilerFPS::GetFpsInfo() 27706f6ba60Sopenharmony_ci{ 27806f6ba60Sopenharmony_ci processFlag = false; 27906f6ba60Sopenharmony_ci fpsInfoMax.fps = 0; 28006f6ba60Sopenharmony_ci std::string uniteLayer; 28106f6ba60Sopenharmony_ci if (!rkFlag) { 28206f6ba60Sopenharmony_ci uniteLayer = "UniRender"; 28306f6ba60Sopenharmony_ci } else { 28406f6ba60Sopenharmony_ci ProfilerFPS &profilerFps = ProfilerFPS::GetInstance(); 28506f6ba60Sopenharmony_ci uniteLayer = profilerFps.GetSurface(); 28606f6ba60Sopenharmony_ci } 28706f6ba60Sopenharmony_ci if (ohFlag) { 28806f6ba60Sopenharmony_ci uniteLayer = GetSurface(); 28906f6ba60Sopenharmony_ci } 29006f6ba60Sopenharmony_ci if (pkgName.empty() || pkgName.find("sceneboard") != std::string::npos) { 29106f6ba60Sopenharmony_ci LOGI("ProfilerFPS.pkgName: %s", pkgName.c_str()); 29206f6ba60Sopenharmony_ci OHOS::SmartPerf::SPUtils::GetCurrentTime(fifty, lastFpsInfoResult.curTime); 29306f6ba60Sopenharmony_ci fpsInfoMax = GetSurfaceFrame(uniteLayer); 29406f6ba60Sopenharmony_ci } else { 29506f6ba60Sopenharmony_ci bool onTop = OHOS::SmartPerf::SPUtils::IsForeGround(pkgName); 29606f6ba60Sopenharmony_ci if (onTop) { 29706f6ba60Sopenharmony_ci OHOS::SmartPerf::SPUtils::GetCurrentTime(fifty, lastFpsInfoResult.curTime); 29806f6ba60Sopenharmony_ci fpsInfoMax = GetSurfaceFrame(uniteLayer); 29906f6ba60Sopenharmony_ci } else { 30006f6ba60Sopenharmony_ci LOGI("ProfilerFPS::app is in the background"); 30106f6ba60Sopenharmony_ci if (processId.empty()) { 30206f6ba60Sopenharmony_ci processFlag = true; 30306f6ba60Sopenharmony_ci fpsInfoMax.Clear(); 30406f6ba60Sopenharmony_ci } else { 30506f6ba60Sopenharmony_ci fpsInfoMax.Clear(); 30606f6ba60Sopenharmony_ci } 30706f6ba60Sopenharmony_ci } 30806f6ba60Sopenharmony_ci } 30906f6ba60Sopenharmony_ci return fpsInfoMax; 31006f6ba60Sopenharmony_ci} 31106f6ba60Sopenharmony_ci 31206f6ba60Sopenharmony_ciFpsInfoProfiler ProfilerFPS::GetSurfaceFrame(std::string name) 31306f6ba60Sopenharmony_ci{ 31406f6ba60Sopenharmony_ci if (name == "") { 31506f6ba60Sopenharmony_ci return FpsInfoProfiler(); 31606f6ba60Sopenharmony_ci } 31706f6ba60Sopenharmony_ci static std::map<std::string, FpsInfoProfiler> fpsMap; 31806f6ba60Sopenharmony_ci if (fpsMap.count(name) == 0) { 31906f6ba60Sopenharmony_ci FpsInfoProfiler tmp; 32006f6ba60Sopenharmony_ci tmp.fps = 0; 32106f6ba60Sopenharmony_ci fpsMap[name] = tmp; 32206f6ba60Sopenharmony_ci } 32306f6ba60Sopenharmony_ci fpsInfo = fpsMap[name]; 32406f6ba60Sopenharmony_ci fpsInfo.fps = 0; 32506f6ba60Sopenharmony_ci FILE *fp; 32606f6ba60Sopenharmony_ci static char tmp[1024]; 32706f6ba60Sopenharmony_ci GetTimeDiff(); 32806f6ba60Sopenharmony_ci std::string cmd = "hidumper -s 10 -a \"fps " + name + "\""; 32906f6ba60Sopenharmony_ci if (cmd.empty()) { 33006f6ba60Sopenharmony_ci LOGE("cmd is null"); 33106f6ba60Sopenharmony_ci return fpsInfo; 33206f6ba60Sopenharmony_ci } 33306f6ba60Sopenharmony_ci fp = popen(cmd.c_str(), "r"); 33406f6ba60Sopenharmony_ci if (fp == nullptr) { 33506f6ba60Sopenharmony_ci LOGE("Failed to open hidumper file"); 33606f6ba60Sopenharmony_ci return fpsInfo; 33706f6ba60Sopenharmony_ci } 33806f6ba60Sopenharmony_ci fpsNum = 0; 33906f6ba60Sopenharmony_ci prevScreenTimestamp = -1; 34006f6ba60Sopenharmony_ci LOGI("ProfilerFPS dump time: start!"); 34106f6ba60Sopenharmony_ci struct timespec time1 = { 0 }; 34206f6ba60Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &time1); 34306f6ba60Sopenharmony_ci fpsInfo.curTime = static_cast<int>(time1.tv_sec - 1); 34406f6ba60Sopenharmony_ci fpsInfo.currTimeDump = (time1.tv_sec - 1) * mod + time1.tv_nsec; 34506f6ba60Sopenharmony_ci LOGI("ProfilerFPS fpsInfo.curTime: %d", fpsInfo.curTime); 34606f6ba60Sopenharmony_ci while (fgets(tmp, sizeof(tmp), fp) != nullptr) { 34706f6ba60Sopenharmony_ci std::string str(tmp); 34806f6ba60Sopenharmony_ci LOGD("ProfilerFPS dump time: %s", str.c_str()); 34906f6ba60Sopenharmony_ci curScreenTimestamp = 0; 35006f6ba60Sopenharmony_ci std::stringstream sstream; 35106f6ba60Sopenharmony_ci sstream << tmp; 35206f6ba60Sopenharmony_ci sstream >> curScreenTimestamp; 35306f6ba60Sopenharmony_ci if (curScreenTimestamp == 0) { 35406f6ba60Sopenharmony_ci continue; 35506f6ba60Sopenharmony_ci } 35606f6ba60Sopenharmony_ci CalcFpsAndJitters(); 35706f6ba60Sopenharmony_ci } 35806f6ba60Sopenharmony_ci pclose(fp); 35906f6ba60Sopenharmony_ci LOGI("ProfilerFPS fpsNum: %d", fpsNum); 36006f6ba60Sopenharmony_ci return fpsInfo; 36106f6ba60Sopenharmony_ci} 36206f6ba60Sopenharmony_ci 36306f6ba60Sopenharmony_civoid ProfilerFPS::CalcFpsAndJitters() 36406f6ba60Sopenharmony_ci{ 36506f6ba60Sopenharmony_ci std::string onScreenTime = std::to_string(curScreenTimestamp / mod); 36606f6ba60Sopenharmony_ci std::string fpsCurTime = std::to_string(fpsInfo.curTime); 36706f6ba60Sopenharmony_ci if (onScreenTime.find(fpsCurTime) != std::string::npos) { 36806f6ba60Sopenharmony_ci fpsNum++; 36906f6ba60Sopenharmony_ci fpsInfo.currTimeStamps.push_back(curScreenTimestamp); 37006f6ba60Sopenharmony_ci } 37106f6ba60Sopenharmony_ci fpsInfo.fps = fpsNum; 37206f6ba60Sopenharmony_ci if (onScreenTime == fpsCurTime) { 37306f6ba60Sopenharmony_ci long long jitter; 37406f6ba60Sopenharmony_ci if (prevScreenTimestamp != -1) { 37506f6ba60Sopenharmony_ci jitter = curScreenTimestamp - prevScreenTimestamp; 37606f6ba60Sopenharmony_ci fpsInfo.jitters.push_back(jitter); 37706f6ba60Sopenharmony_ci } else { 37806f6ba60Sopenharmony_ci if (prevlastScreenTimestamp != 0 && (curScreenTimestamp - prevlastScreenTimestamp) < mod) { 37906f6ba60Sopenharmony_ci jitter = curScreenTimestamp - prevlastScreenTimestamp; 38006f6ba60Sopenharmony_ci fpsInfo.jitters.push_back(jitter); 38106f6ba60Sopenharmony_ci } else { 38206f6ba60Sopenharmony_ci jitter = curScreenTimestamp - curScreenTimestamp / mod * mod; 38306f6ba60Sopenharmony_ci fpsInfo.jitters.push_back(jitter); 38406f6ba60Sopenharmony_ci } 38506f6ba60Sopenharmony_ci } 38606f6ba60Sopenharmony_ci prevScreenTimestamp = curScreenTimestamp; 38706f6ba60Sopenharmony_ci prevlastScreenTimestamp = curScreenTimestamp; 38806f6ba60Sopenharmony_ci } 38906f6ba60Sopenharmony_ci} 39006f6ba60Sopenharmony_ci 39106f6ba60Sopenharmony_civoid ProfilerFPS::GetOhFps(std::vector<std::string> v) 39206f6ba60Sopenharmony_ci{ 39306f6ba60Sopenharmony_ci if (v[number] == "") { 39406f6ba60Sopenharmony_ci printf("the args of num must be not-null!\n"); 39506f6ba60Sopenharmony_ci } else { 39606f6ba60Sopenharmony_ci this->num = atoi(v[number].c_str()); 39706f6ba60Sopenharmony_ci if (this->num < 0) { 39806f6ba60Sopenharmony_ci printf("set num:%d not vaild arg\n", this->num); 39906f6ba60Sopenharmony_ci } 40006f6ba60Sopenharmony_ci printf("set num:%d success\n", this->num); 40106f6ba60Sopenharmony_ci ohFlag = true; 40206f6ba60Sopenharmony_ci int sectionsNum; 40306f6ba60Sopenharmony_ci if (static_cast<int>(v.size()) < four) { 40406f6ba60Sopenharmony_ci sectionsNum = 0; 40506f6ba60Sopenharmony_ci } else { 40606f6ba60Sopenharmony_ci sectionsNum = atoi(v[four].c_str()); 40706f6ba60Sopenharmony_ci } 40806f6ba60Sopenharmony_ci for (int i = 0; i < this->num; i++) { 40906f6ba60Sopenharmony_ci GetResultFPS(sectionsNum); 41006f6ba60Sopenharmony_ci } 41106f6ba60Sopenharmony_ci } 41206f6ba60Sopenharmony_ci printf("SP_daemon exec finished!\n"); 41306f6ba60Sopenharmony_ci} 41406f6ba60Sopenharmony_ci 41506f6ba60Sopenharmony_civoid ProfilerFPS::SetGameLayer(std::string isGameView) 41606f6ba60Sopenharmony_ci{ 41706f6ba60Sopenharmony_ci isGameLayer = std::move(isGameView); 41806f6ba60Sopenharmony_ci} 41906f6ba60Sopenharmony_ci 42006f6ba60Sopenharmony_ciFpsInfoProfiler ProfilerFPS::selfRerderLayers(const std::string &gameLayer) 42106f6ba60Sopenharmony_ci{ 42206f6ba60Sopenharmony_ci OHOS::SmartPerf::SPUtils::GetCurrentTime(fifty, lastFpsInfoResult.curTime); 42306f6ba60Sopenharmony_ci fpsInfoMax = GetSurfaceFrame(gameLayer); 42406f6ba60Sopenharmony_ci return fpsInfoMax; 42506f6ba60Sopenharmony_ci} 42606f6ba60Sopenharmony_ci 42706f6ba60Sopenharmony_cistd::string ProfilerFPS::GetGameLayer() 42806f6ba60Sopenharmony_ci{ 42906f6ba60Sopenharmony_ci std::string gameLayer = ""; 43006f6ba60Sopenharmony_ci if (processId.empty()) { 43106f6ba60Sopenharmony_ci return gameLayer; 43206f6ba60Sopenharmony_ci } 43306f6ba60Sopenharmony_ci std::string cmdResult; 43406f6ba60Sopenharmony_ci std::string dumperSurface = HIDUMPER_CMD_MAP.at(HidumperCmd::DUMPER_SURFACE); 43506f6ba60Sopenharmony_ci SPUtils::LoadCmd(dumperSurface, cmdResult); 43606f6ba60Sopenharmony_ci LOGI("ProfilerFPS::cmdResult: (%s)", cmdResult.c_str()); 43706f6ba60Sopenharmony_ci std::string start = "NodeId["; 43806f6ba60Sopenharmony_ci std::string end = "]"; 43906f6ba60Sopenharmony_ci size_t startPos = cmdResult.find(start) + start.length(); 44006f6ba60Sopenharmony_ci size_t endPos = cmdResult.find(end, startPos); 44106f6ba60Sopenharmony_ci std::string nodeIdStr = cmdResult.substr(startPos, endPos - startPos); 44206f6ba60Sopenharmony_ci LOGI("ProfilerFPS::nodeIdStr: (%s)", nodeIdStr.c_str()); 44306f6ba60Sopenharmony_ci uint64_t nodeId; 44406f6ba60Sopenharmony_ci const int kShiftAmount = 32; 44506f6ba60Sopenharmony_ci if (!nodeIdStr.empty()) { 44606f6ba60Sopenharmony_ci std::stringstream ss(nodeIdStr); 44706f6ba60Sopenharmony_ci ss >> nodeId; 44806f6ba60Sopenharmony_ci if (ss.fail() || !ss.eof()) { 44906f6ba60Sopenharmony_ci return gameLayer; 45006f6ba60Sopenharmony_ci } 45106f6ba60Sopenharmony_ci nodeId = nodeId >> kShiftAmount; 45206f6ba60Sopenharmony_ci LOGI("ProfilerFPS::nodeId: (%d)", nodeId); 45306f6ba60Sopenharmony_ci if (std::to_string(nodeId) == processId) { 45406f6ba60Sopenharmony_ci size_t layerStartPos = cmdResult.find("["); 45506f6ba60Sopenharmony_ci size_t layerEndPos = cmdResult.find("]"); 45606f6ba60Sopenharmony_ci if (layerEndPos - layerStartPos <= 1 && layerEndPos > endPos) { 45706f6ba60Sopenharmony_ci return gameLayer; 45806f6ba60Sopenharmony_ci } 45906f6ba60Sopenharmony_ci layerStartPos += 1; 46006f6ba60Sopenharmony_ci gameLayer = cmdResult.substr(layerStartPos, layerEndPos - layerStartPos); 46106f6ba60Sopenharmony_ci } 46206f6ba60Sopenharmony_ci } 46306f6ba60Sopenharmony_ci LOGI("ProfilerFPS::gameLayer: (%s)", gameLayer.c_str()); 46406f6ba60Sopenharmony_ci return gameLayer; 46506f6ba60Sopenharmony_ci} 46606f6ba60Sopenharmony_civoid ProfilerFPS::SetRkFlag() 46706f6ba60Sopenharmony_ci{ 46806f6ba60Sopenharmony_ci rkFlag = true; 46906f6ba60Sopenharmony_ci} 47006f6ba60Sopenharmony_ci} 47106f6ba60Sopenharmony_ci}