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/GpuCounterCallback.h" 25 #include "include/service_plugin.h" 26 27 namespace OHOS { 28 namespace SmartPerf { ItemData()29 std::map<std::string, std::string> GpuCounter::ItemData() 30 { 31 return std::map<std::string, std::string>(); 32 } 33 StartCollect(GcCollectType type)34 void GpuCounter::StartCollect(GcCollectType type) 35 { 36 std::unique_ptr<GpuCounterCallback> gpuCounterCallback = std::make_unique<GpuCounterCallbackImpl>(); 37 38 const int duration = 1000; 39 40 ServicePluginHandler &servicePluginHandler = ServicePluginHandler::GetInstance(); 41 void* handle = servicePluginHandler.GetSoHandler(ServicePluginHandler::ServicePluginType::GAME_PLUGIN); 42 if (!handle) { 43 WLOGE("Get service plugin handler failed."); 44 return; 45 } 46 47 typedef GameServicePlugin *(*GetServicePlugin)(); 48 GetServicePlugin servicePlugin = (GetServicePlugin)dlsym(handle, createPlugin.c_str()); 49 if (!servicePlugin) { 50 WLOGE("GameServicePlugin Error loading symbol"); 51 return; 52 } 53 54 if (type == GC_START && gcStatus == GC_INIT) { 55 gpuCounterData.clear(); 56 gpuCounterRealtimeData.clear(); 57 int ret = servicePlugin()->StartGetGpuPerfInfo(duration, std::move(gpuCounterCallback)); 58 if (ret == 0) { 59 gcStatus = GC_RUNNING; 60 } else { 61 WLOGE("GpuCounter call gameService error, ret = %d", ret); 62 } 63 } else if (type == GC_RESTART && gcStatus == GC_RUNNING) { 64 int ret = servicePlugin()->StartGetGpuPerfInfo(duration, std::move(gpuCounterCallback)); 65 if (ret != 0) { 66 WLOGE("GpuCounter call gameService error, ret = %d", ret); 67 } 68 } else { 69 WLOGE("GpuCounter state error, type: %d, state: %d", type, gcStatus); 70 } 71 } 72 SaveData(std::string path)73 void GpuCounter::SaveData(std::string path) 74 { 75 if (gcStatus != GC_RUNNING || gpuCounterData.size() <= 0) { 76 return; 77 } 78 char gpuCounterDataDirChar[PATH_MAX] = {0x00}; 79 if (realpath(path.c_str(), gpuCounterDataDirChar) == nullptr) { 80 WLOGE("data dir %s is nullptr", path.c_str()); 81 return; 82 } 83 std::string gpuCounterDataPath = std::string(gpuCounterDataDirChar) + "/gpu_counter.csv"; 84 std::ofstream outFile; 85 std::mutex mtx; 86 mtx.lock(); 87 outFile.open(gpuCounterDataPath.c_str(), std::ios::out | std::ios::trunc); 88 if (!outFile.is_open()) { 89 WLOGE("open GpuCounter data file failed."); 90 return; 91 } 92 std::string title = "startTime," 93 "duration," 94 "gpuActive," 95 "drawCalls," 96 "primitives," 97 "vertexCounts," 98 "totalInstruments," 99 "gpuLoadPercentage," 100 "vertexLoadPercentage," 101 "fragmentLoadPercentage," 102 "computeLoadPercentage," 103 "textureLoadPercentage," 104 "memoryReadBandwidth," 105 "memoryWriteBandwidth," 106 "memoryBandwidthPercentage\r"; 107 outFile << title << std::endl; 108 for (unsigned int i = 0; i < gpuCounterSaveReportData.size() - 1; i++) { 109 outFile << gpuCounterSaveReportData[i] << std::endl; 110 } 111 outFile.close(); 112 mtx.unlock(); 113 } 114 GetGpuCounterData()115 std::vector<std::string> &GpuCounter::GetGpuCounterData() 116 { 117 return gpuCounterData; 118 } 119 GetGpuCounterSaveReportData()120 std::vector<std::string> &GpuCounter::GetGpuCounterSaveReportData() 121 { 122 return gpuCounterSaveReportData; 123 } 124 GetRealtimeDataLock()125 std::mutex &GpuCounter::GetRealtimeDataLock() 126 { 127 return realtimeDataLock; 128 } 129 GetGpuCounterRealtimeData()130 std::string &GpuCounter::GetGpuCounterRealtimeData() 131 { 132 return gpuCounterRealtimeData; 133 } AddGpuCounterRealtimeData(std::string dataString)134 void GpuCounter::AddGpuCounterRealtimeData(std::string dataString) 135 { 136 gpuCounterRealtimeData += dataString; 137 } 138 GetGpuRealtimeData(std::map<std::string,std::string> & dataMap)139 void GpuCounter::GetGpuRealtimeData(std::map<std::string, std::string> &dataMap) 140 { 141 if (gpuCounterRealtimeData.size() > 0) { 142 std::map<std::string, std::string> gpuCounterRealtimeDataMap; 143 gpuCounterRealtimeDataMap["gpuCounterData"] = gpuCounterRealtimeData; 144 realtimeDataLock.lock(); 145 dataMap.insert(gpuCounterRealtimeDataMap.begin(), gpuCounterRealtimeDataMap.end()); 146 realtimeDataLock.unlock(); 147 gpuCounterRealtimeData.clear(); 148 } 149 } 150 StopCollect()151 void GpuCounter::StopCollect() 152 { 153 if (gcStatus != GC_RUNNING) { 154 return; 155 } 156 ServicePluginHandler &servicePluginHandler = ServicePluginHandler::GetInstance(); 157 void* handle = servicePluginHandler.GetSoHandler(ServicePluginHandler::ServicePluginType::GAME_PLUGIN); 158 if (!handle) { 159 WLOGE("Get service plugin handler failed."); 160 return; 161 } 162 163 typedef GameServicePlugin *(*GetServicePlugin)(); 164 GetServicePlugin servicePlugin = (GetServicePlugin)dlsym(handle, createPlugin.c_str()); 165 if (!servicePlugin) { 166 WLOGE("GameServicePlugin Error loading symbol"); 167 return; 168 } 169 170 int ret = servicePlugin()->StopGetGpuPerfInfo(); 171 if (ret == 0) { 172 gcStatus = GC_INIT; 173 } 174 } 175 } 176 }