• 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 "chrono"
17 #include "string"
18 #include "thread"
19 #include "fstream"
20 #include <iostream>
21 #include <dlfcn.h>
22 #include "include/sp_log.h"
23 #include "include/GpuCounter.h"
24 #include "include/service_plugin.h"
25 #include "interface/GpuCounterCallback.h"
26 #include "interface/GameServicePlugin.h"
27 
28 namespace OHOS {
29     namespace SmartPerf {
ItemData()30         std::map<std::string, std::string> GpuCounter::ItemData()
31         {
32             std::map<std::string, std::string> gpuCounterDataMap;
33             LOGI("GpuCounter:ItemData map size(%u)", gpuCounterDataMap.size());
34             return gpuCounterDataMap;
35         }
36 
StartExecutionOnce(bool isPause)37         void GpuCounter::StartExecutionOnce(bool isPause)
38         {
39             StartCollect(GpuCounter::GC_START);
40         }
41 
FinishtExecutionOnce(bool isPause)42         void GpuCounter::FinishtExecutionOnce(bool isPause)
43         {
44             std::unique_lock<std::mutex> lock(gpuCounterLock);
45             SaveData(savePathDirectory_);
46             StopCollect();
47             if (!isPause_) {
48                 gpuCounterData.clear();
49             }
50         }
51 
SetSavePathDirectory(const std::string & dir)52         void GpuCounter::SetSavePathDirectory(const std::string& dir)
53         {
54             savePathDirectory_ = dir;
55         }
56 
StartCollect(GcCollectType type)57         void GpuCounter::StartCollect(GcCollectType type)
58         {
59             if (frequency == 0) {
60                 WLOGE("GpuCounter frequency is not set");
61                 return;
62             }
63             std::unique_ptr<GpuCounterCallback> gpuCounterCallback = std::make_unique<GpuCounterCallbackImpl>();
64 
65             // 1s 一次Gameservice回调
66             const int duration = 1000;
67 
68             ServicePluginHandler &servicePluginHandler = ServicePluginHandler::GetInstance();
69             void* handle = servicePluginHandler.GetSoHandler(ServicePluginHandler::ServicePluginType::GAME_PLUGIN);
70             if (!handle) {
71                 WLOGE("Get service plugin handler failed.");
72                 return;
73             }
74 
75             typedef GameServicePlugin *(*GetServicePlugin)();
76             GetServicePlugin servicePlugin = (GetServicePlugin)dlsym(handle, createPlugin.c_str());
77             if (!servicePlugin) {
78                 WLOGE("GameServicePlugin Error loading symbol");
79                 return;
80             }
81 
82             if (type == GC_START && gcStatus == GC_INIT) {
83                 if (!isPause_) {
84                     gpuCounterData.clear();
85                     gpuCounterRealtimeData.clear();
86                 }
87                 int ret = servicePlugin()->StartGetGpuPerfInfo(duration, frequency, std::move(gpuCounterCallback));
88                 if (ret == 0) {
89                     gcStatus = GC_RUNNING;
90                 } else {
91                     WLOGE("GpuCounter call gameService error, ret = %d", ret);
92                 }
93             } else if (type == GC_RESTART && gcStatus == GC_RUNNING) {
94                 int ret = servicePlugin()->StartGetGpuPerfInfo(duration, frequency, std::move(gpuCounterCallback));
95                 if (ret != 0) {
96                     WLOGE("GpuCounter call gameService error, ret = %d", ret);
97                 }
98             } else {
99                 WLOGE("GpuCounter state error, type: %d, state: %d", type, gcStatus);
100             }
101         }
102 
SaveData(const std::string & path)103         void GpuCounter::SaveData(const std::string& path)
104         {
105             // device与editor采集都会走tcp stop时的SaveData,但是deivce同时会走FinishtExecutionOnce导致SaveData执行两次
106             // 目前device在第一次保存数据后会清空,第二次SaveData实际不生效
107             if (gcStatus != GC_RUNNING || gpuCounterData.size() <= 0 || path.empty()) {
108                 return;
109             }
110             savePathDirectory_ = path;
111             char gpuCounterDataDirChar[PATH_MAX] = {0x00};
112             if (realpath(path.c_str(), gpuCounterDataDirChar) == nullptr) {
113                 WLOGE("data dir %s is nullptr", path.c_str());
114                 return;
115             }
116             std::string gpuCounterDataPath = std::string(gpuCounterDataDirChar) + "/gpu_counter.csv";
117             std::ofstream outFile;
118             outFile.open(gpuCounterDataPath.c_str(), std::ios::out | std::ios::trunc);
119             if (!outFile.is_open()) {
120                 WLOGE("open GpuCounter data file failed. %s", gpuCounterDataPath.c_str());
121                 return;
122             }
123             static const std::string title = "startTime,"
124                 "duration,"
125                 "gpuActive,"
126                 "drawCalls,"
127                 "primitives,"
128                 "vertexCounts,"
129                 "totalInstruments,"
130                 "gpuLoadPercentage,"
131                 "vertexLoadPercentage,"
132                 "fragmentLoadPercentage,"
133                 "computeLoadPercentage,"
134                 "textureLoadPercentage,"
135                 "memoryReadBandwidth,"
136                 "memoryWriteBandwidth,"
137                 "memoryBandwidthPercentage\r";
138             outFile << title << std::endl;
139             std::unique_lock<std::mutex> lock(realtimeDataLock);
140             for (unsigned int i = 0; i < gpuCounterSaveReportData.size() - 1; i++) {
141                 outFile << gpuCounterSaveReportData[i] << std::endl;
142             }
143             outFile.close();
144         }
145 
GetGpuCounterData()146         std::vector<std::string> &GpuCounter::GetGpuCounterData()
147         {
148             return gpuCounterData;
149         }
150 
GetGpuCounterSaveReportData()151         std::vector<std::string> &GpuCounter::GetGpuCounterSaveReportData()
152         {
153             return gpuCounterSaveReportData;
154         }
155 
GetGpuRealtimeData()156         std::map<std::string, std::string> GpuCounter::GetGpuRealtimeData()
157         {
158             std::unique_lock<std::mutex> lock(realtimeDataLock);
159             std::map<std::string, std::string> gpuCounterDataMap = {};
160             if (gpuCounterRealtimeData.size() > 0) {
161                 gpuCounterDataMap.insert({"gpuCounterData", gpuCounterRealtimeData});
162                 gpuCounterRealtimeData.clear();
163             }
164             return gpuCounterDataMap;
165         }
AddGpuCounterRealtimeData(const std::string & dataString)166         void GpuCounter::AddGpuCounterRealtimeData(const std::string& dataString)
167         {
168             std::unique_lock<std::mutex> lock(realtimeDataLock);
169             gpuCounterRealtimeData += dataString;
170         }
171 
StopCollect()172         void GpuCounter::StopCollect()
173         {
174             if (gcStatus != GC_RUNNING) {
175                 return;
176             }
177             ServicePluginHandler &servicePluginHandler = ServicePluginHandler::GetInstance();
178             void* handle = servicePluginHandler.GetSoHandler(ServicePluginHandler::ServicePluginType::GAME_PLUGIN);
179             if (!handle) {
180                 WLOGE("Get service plugin handler failed.");
181                 return;
182             }
183 
184             typedef GameServicePlugin *(*GetServicePlugin)();
185             GetServicePlugin servicePlugin = (GetServicePlugin)dlsym(handle, createPlugin.c_str());
186             if (!servicePlugin) {
187                 WLOGE("GameServicePlugin Error loading symbol");
188                 return;
189             }
190 
191             int ret = servicePlugin()->StopGetGpuPerfInfo();
192             if (ret == 0) {
193                 gcStatus = GC_INIT;
194             }
195         }
196 
SetFrequency(const int & freq)197         void GpuCounter::SetFrequency(const int& freq)
198         {
199             frequency = freq;
200         }
201 
GetGpuCounterLock()202         std::mutex &GpuCounter::GetGpuCounterLock()
203         {
204             return gpuCounterLock;
205         }
206 
SetIsPause(bool isPause)207         void GpuCounter::SetIsPause(bool isPause)
208         {
209             isPause_ = isPause;
210         }
211     }
212 }