/* * Copyright (C) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "chrono" #include "string" #include "thread" #include "fstream" #include #include #include "include/sp_log.h" #include "include/GpuCounter.h" #include "include/GpuCounterCallback.h" namespace OHOS { namespace SmartPerf { std::map GpuCounter::ItemData() { return std::map(); } void* GpuCounter::GetSoHandle() { char soFilePathChar[PATH_MAX] = {0x00}; if ((realpath(PLUGIN_SO_PATH.c_str(), soFilePathChar) == nullptr)) { LOGE("%s is not exist.", PLUGIN_SO_PATH.c_str()); return nullptr; } void* handle = dlopen(soFilePathChar, RTLD_LAZY); if (!handle) { LOGI("open GpuCounterPlugin so file error."); return nullptr; } return handle; } void GpuCounter::StartCollect(GcCollectType type) { std::unique_ptr gpuCounterCallback = std::make_unique(); const int duration = 1000; void* handle = GetSoHandle(); if (!handle) { return; } typedef GpuCounterPlugin *(*GetGpuCounterPlugin)(); GetGpuCounterPlugin startGetGpuPerfInfo = (GetGpuCounterPlugin)dlsym(handle, CREATE_PLUGIN.c_str()); if (type == GC_START && gcStatus == GC_INIT) { gpuCounterData.clear(); gpuCounterRealtimeData.clear(); int ret = startGetGpuPerfInfo()->StartGetGpuPerfInfo(duration, std::move(gpuCounterCallback)); if (ret == 0) { gcStatus = GC_RUNNING; LOGI("GpuCounter collect start."); } else { LOGE("GpuCounter call gameService error, ret = %d", ret); } } else if (type == GC_RESTART && gcStatus == GC_RUNNING) { int ret = startGetGpuPerfInfo()->StartGetGpuPerfInfo(duration, std::move(gpuCounterCallback)); if (ret == 0) { LOGI("GpuCounter recollect start."); } else { LOGE("GpuCounter call gameService error, ret = %d", ret); } } else { LOGE("GpuCounter state error, type: %d, state: %d", type, gcStatus); } } void GpuCounter::SaveData(std::string path) { if (gcStatus != GC_RUNNING || gpuCounterData.size() <= 0) { return; } LOGI("GpuCounter collect stop."); char gpuCounterDataDirChar[PATH_MAX] = {0x00}; if (realpath(path.c_str(), gpuCounterDataDirChar) == nullptr) { LOGE("data dir %s is nullptr", path.c_str()); return; } std::string gpuCounterDataPath = std::string(gpuCounterDataDirChar) + "/gpu_counter.csv"; std::ofstream outFile; std::mutex mtx; mtx.lock(); outFile.open(gpuCounterDataPath.c_str(), std::ios::out | std::ios::trunc); if (!outFile.is_open()) { LOGE("open GpuCounter data file failed."); return; } std::string title = "startTime," "duration," "gpuActive," "drawCalls," "primitives," "vertexCounts," "totalInstruments," "gpuLoadPercentage," "vertexLoadPercentage," "fragmentLoadPercentage," "computeLoadPercentage," "textureLoadPercentage," "memoryReadBandwidth," "memoryWriteBandwidth," "memoryBandwidthPercentage\r"; outFile << title << std::endl; for (unsigned int i = 0; i < gpuCounterSaveReportData.size() - 1; i++) { outFile << gpuCounterSaveReportData[i] << std::endl; } outFile.close(); mtx.unlock(); } std::vector &GpuCounter::GetGpuCounterData() { return gpuCounterData; } std::vector &GpuCounter::GetGpuCounterSaveReportData() { return gpuCounterSaveReportData; } std::mutex &GpuCounter::GetRealtimeDataLock() { return realtimeDataLock; } std::string &GpuCounter::GetGpuCounterRealtimeData() { return gpuCounterRealtimeData; } void GpuCounter::AddGpuCounterRealtimeData(std::string dataString) { gpuCounterRealtimeData += dataString; } void GpuCounter::GetGpuRealtimeData(std::map &dataMap) { if (gpuCounterRealtimeData.size() > 0) { std::map gpuCounterRealtimeDataMap; gpuCounterRealtimeDataMap["gpuCounterData"] = gpuCounterRealtimeData; realtimeDataLock.lock(); dataMap.insert(gpuCounterRealtimeDataMap.begin(), gpuCounterRealtimeDataMap.end()); realtimeDataLock.unlock(); gpuCounterRealtimeData.clear(); } } void GpuCounter::StopCollect() { if (gcStatus != GC_RUNNING) { return; } void* handle = GetSoHandle(); if (!handle) { return; } typedef GpuCounterPlugin *(*GetGpuCounterPlugin)(); GetGpuCounterPlugin startGetGpuPerfInfo = (GetGpuCounterPlugin)dlsym(handle, CREATE_PLUGIN.c_str()); int ret = startGetGpuPerfInfo()->StopGetGpuPerfInfo(); if (ret == 0) { gcStatus = GC_INIT; LOGI("GpuCounter collect finish."); } } } }