106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd. 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 1606f6ba60Sopenharmony_ci#include <string> 1706f6ba60Sopenharmony_ci#include <sstream> 1806f6ba60Sopenharmony_ci#include "include/sp_log.h" 1906f6ba60Sopenharmony_ci#include "include/sp_utils.h" 2006f6ba60Sopenharmony_ci#include "include/GpuCounter.h" 2106f6ba60Sopenharmony_ci#include "include/GpuCounterCallback.h" 2206f6ba60Sopenharmony_ci 2306f6ba60Sopenharmony_cinamespace OHOS { 2406f6ba60Sopenharmony_ci namespace SmartPerf { 2506f6ba60Sopenharmony_ci GpuCounterCallbackImpl::GpuCounterCallbackImpl() 2606f6ba60Sopenharmony_ci { 2706f6ba60Sopenharmony_ci GpuPerfInfo firstData; 2806f6ba60Sopenharmony_ci firstData.startTime = SPUtils::GetCurTime(); 2906f6ba60Sopenharmony_ci firstData.duration = 0; 3006f6ba60Sopenharmony_ci firstData.gpuActive = 0; 3106f6ba60Sopenharmony_ci firstData.drawCalls = 0; 3206f6ba60Sopenharmony_ci firstData.primitives = 0; 3306f6ba60Sopenharmony_ci firstData.vertexCounts = 0; 3406f6ba60Sopenharmony_ci firstData.totalInstruments = 0; 3506f6ba60Sopenharmony_ci firstData.gpuLoadPercentage = 0; 3606f6ba60Sopenharmony_ci firstData.vertexLoadPercentage = 0; 3706f6ba60Sopenharmony_ci firstData.fragmentLoadPercentage = 0; 3806f6ba60Sopenharmony_ci firstData.computeLoadPercentage = 0; 3906f6ba60Sopenharmony_ci firstData.textureLoadPercentage = 0; 4006f6ba60Sopenharmony_ci firstData.memoryReadBandwidth = 0; 4106f6ba60Sopenharmony_ci firstData.memoryWriteBandwidth = 0; 4206f6ba60Sopenharmony_ci firstData.memoryBandwidthPercentage = 0; 4306f6ba60Sopenharmony_ci firstData.remainTime = maxTime; 4406f6ba60Sopenharmony_ci realtimeGpuPerfInfoData = firstData; 4506f6ba60Sopenharmony_ci gpuCounter.push_back(firstData); 4606f6ba60Sopenharmony_ci } 4706f6ba60Sopenharmony_ci 4806f6ba60Sopenharmony_ci 4906f6ba60Sopenharmony_ci unsigned long long GpuCounterCallbackImpl::JoinSocketDataPercentFunction(uint32_t itemFirst, 5006f6ba60Sopenharmony_ci int32_t durationFirst, uint32_t itemSecond, int32_t durationSecond) const 5106f6ba60Sopenharmony_ci { 5206f6ba60Sopenharmony_ci return (static_cast<unsigned long long>(itemFirst) * static_cast<unsigned long long>(durationFirst) + 5306f6ba60Sopenharmony_ci static_cast<unsigned long long>(itemSecond) * static_cast<unsigned long long>(durationSecond)) / 5406f6ba60Sopenharmony_ci (static_cast<unsigned long long>(durationFirst) + static_cast<unsigned long long>(durationSecond)); 5506f6ba60Sopenharmony_ci } 5606f6ba60Sopenharmony_ci 5706f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::JoinSocketDataValue(GpuPerfInfo *newData) 5806f6ba60Sopenharmony_ci { 5906f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.gpuActive += newData->gpuActive; 6006f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.drawCalls += newData->drawCalls; 6106f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.primitives += newData->primitives; 6206f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.vertexCounts += newData->vertexCounts; 6306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.totalInstruments += newData->totalInstruments; 6406f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryReadBandwidth += newData->memoryReadBandwidth; 6506f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryWriteBandwidth += newData->memoryWriteBandwidth; 6606f6ba60Sopenharmony_ci } 6706f6ba60Sopenharmony_ci 6806f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::JoinSocketDataPercent(GpuPerfInfo *newData) 6906f6ba60Sopenharmony_ci { 7006f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.gpuLoadPercentage = JoinSocketDataPercentFunction( 7106f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.gpuLoadPercentage, realtimeGpuPerfInfoData.duration, 7206f6ba60Sopenharmony_ci newData->gpuLoadPercentage, newData->duration); 7306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.vertexLoadPercentage = JoinSocketDataPercentFunction( 7406f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.vertexLoadPercentage, realtimeGpuPerfInfoData.duration, 7506f6ba60Sopenharmony_ci newData->vertexLoadPercentage, newData->duration); 7606f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.fragmentLoadPercentage = JoinSocketDataPercentFunction( 7706f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.fragmentLoadPercentage, realtimeGpuPerfInfoData.duration, 7806f6ba60Sopenharmony_ci newData->fragmentLoadPercentage, newData->duration); 7906f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.computeLoadPercentage = JoinSocketDataPercentFunction( 8006f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.computeLoadPercentage, realtimeGpuPerfInfoData.duration, 8106f6ba60Sopenharmony_ci newData->computeLoadPercentage, newData->duration); 8206f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.textureLoadPercentage = JoinSocketDataPercentFunction( 8306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.textureLoadPercentage, realtimeGpuPerfInfoData.duration, 8406f6ba60Sopenharmony_ci newData->textureLoadPercentage, newData->duration); 8506f6ba60Sopenharmony_ci } 8606f6ba60Sopenharmony_ci 8706f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::JoinSocketData(GpuPerfInfo *newData) 8806f6ba60Sopenharmony_ci { 8906f6ba60Sopenharmony_ci JoinSocketDataValue(newData); 9006f6ba60Sopenharmony_ci JoinSocketDataPercent(newData); 9106f6ba60Sopenharmony_ci 9206f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration += newData->duration; 9306f6ba60Sopenharmony_ci } 9406f6ba60Sopenharmony_ci 9506f6ba60Sopenharmony_ci unsigned long long GpuCounterCallbackImpl::SplitSocketDataValueFunction(uint32_t value, int32_t interval, 9606f6ba60Sopenharmony_ci int32_t duration) const 9706f6ba60Sopenharmony_ci { 9806f6ba60Sopenharmony_ci return static_cast<unsigned long long>(value) * 9906f6ba60Sopenharmony_ci static_cast<unsigned long long>(interval) / 10006f6ba60Sopenharmony_ci static_cast<unsigned long long>(duration); 10106f6ba60Sopenharmony_ci } 10206f6ba60Sopenharmony_ci 10306f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::SplitSocketDataValue(int32_t interval) 10406f6ba60Sopenharmony_ci { 10506f6ba60Sopenharmony_ci GpuCounter &gpuCounterInstance = GpuCounter::GetInstance(); 10606f6ba60Sopenharmony_ci 10706f6ba60Sopenharmony_ci unsigned long long gpuActiveTargetValue = SplitSocketDataValueFunction( 10806f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.gpuActive, interval, 10906f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 11006f6ba60Sopenharmony_ci unsigned long long drawCallsTargetValue = SplitSocketDataValueFunction( 11106f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.drawCalls, interval, 11206f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 11306f6ba60Sopenharmony_ci unsigned long long primitivesTargetValue = SplitSocketDataValueFunction( 11406f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.primitives, interval, 11506f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 11606f6ba60Sopenharmony_ci unsigned long long vertexCountsTargetValue = SplitSocketDataValueFunction( 11706f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.vertexCounts, interval, 11806f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 11906f6ba60Sopenharmony_ci unsigned long long totalInstrumentsTargetValue = SplitSocketDataValueFunction( 12006f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.totalInstruments, interval, 12106f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 12206f6ba60Sopenharmony_ci unsigned long long memoryReadBandwidthTargetValue = SplitSocketDataValueFunction( 12306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryReadBandwidth, interval, 12406f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 12506f6ba60Sopenharmony_ci unsigned long long memoryWriteBandwidthTargetValue = SplitSocketDataValueFunction( 12606f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryWriteBandwidth, interval, 12706f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration); 12806f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 12906f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.gpuActive - gpuActiveTargetValue) + "_"); 13006f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 13106f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.drawCalls - drawCallsTargetValue) + "_"); 13206f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 13306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.primitives - primitivesTargetValue) + "_"); 13406f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 13506f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.vertexCounts - vertexCountsTargetValue) + "_"); 13606f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 13706f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.totalInstruments - totalInstrumentsTargetValue) + "_"); 13806f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 13906f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryReadBandwidth - memoryReadBandwidthTargetValue) + "_"); 14006f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData(std::to_string( 14106f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryWriteBandwidth - memoryWriteBandwidthTargetValue) + "_"); 14206f6ba60Sopenharmony_ci 14306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.gpuActive = gpuActiveTargetValue; 14406f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.drawCalls = drawCallsTargetValue; 14506f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.primitives = primitivesTargetValue; 14606f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.vertexCounts = vertexCountsTargetValue; 14706f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.totalInstruments = totalInstrumentsTargetValue; 14806f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryReadBandwidth = memoryReadBandwidthTargetValue; 14906f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.memoryWriteBandwidth = memoryWriteBandwidthTargetValue; 15006f6ba60Sopenharmony_ci } 15106f6ba60Sopenharmony_ci 15206f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::SplitSocketDataPercent() 15306f6ba60Sopenharmony_ci { 15406f6ba60Sopenharmony_ci GpuCounter &gpuCounterInstance = GpuCounter::GetInstance(); 15506f6ba60Sopenharmony_ci 15606f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData( 15706f6ba60Sopenharmony_ci std::to_string(realtimeGpuPerfInfoData.gpuLoadPercentage) + "_"); 15806f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData( 15906f6ba60Sopenharmony_ci std::to_string(realtimeGpuPerfInfoData.vertexLoadPercentage) + "_"); 16006f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData( 16106f6ba60Sopenharmony_ci std::to_string(realtimeGpuPerfInfoData.fragmentLoadPercentage) + "_"); 16206f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData( 16306f6ba60Sopenharmony_ci std::to_string(realtimeGpuPerfInfoData.computeLoadPercentage) + "_"); 16406f6ba60Sopenharmony_ci gpuCounterInstance.AddGpuCounterRealtimeData( 16506f6ba60Sopenharmony_ci std::to_string(realtimeGpuPerfInfoData.textureLoadPercentage) + ";"); 16606f6ba60Sopenharmony_ci } 16706f6ba60Sopenharmony_ci 16806f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::SplitSocketData() 16906f6ba60Sopenharmony_ci { 17006f6ba60Sopenharmony_ci int32_t interval = realtimeGpuPerfInfoData.duration - maxDuration; 17106f6ba60Sopenharmony_ci SplitSocketDataValue(interval); 17206f6ba60Sopenharmony_ci SplitSocketDataPercent(); 17306f6ba60Sopenharmony_ci realtimeGpuPerfInfoData.duration = interval; 17406f6ba60Sopenharmony_ci } 17506f6ba60Sopenharmony_ci 17606f6ba60Sopenharmony_ci void GpuCounterCallbackImpl::GetRealTime(GpuPerfInfo *newData) 17706f6ba60Sopenharmony_ci { 17806f6ba60Sopenharmony_ci GpuCounter &gpuCounterInstance = GpuCounter::GetInstance(); 17906f6ba60Sopenharmony_ci 18006f6ba60Sopenharmony_ci JoinSocketData(newData); 18106f6ba60Sopenharmony_ci if ((realtimeGpuPerfInfoData.duration == 0) || (newData->duration == 0)) { 18206f6ba60Sopenharmony_ci return; 18306f6ba60Sopenharmony_ci } 18406f6ba60Sopenharmony_ci gpuCounterInstance.GetRealtimeDataLock().lock(); 18506f6ba60Sopenharmony_ci while (realtimeGpuPerfInfoData.duration >= maxDuration) { 18606f6ba60Sopenharmony_ci SplitSocketData(); 18706f6ba60Sopenharmony_ci } 18806f6ba60Sopenharmony_ci gpuCounterInstance.GetRealtimeDataLock().unlock(); 18906f6ba60Sopenharmony_ci } 19006f6ba60Sopenharmony_ci 19106f6ba60Sopenharmony_ci int GpuCounterCallbackImpl::OnGpuData(std::vector <GpuPerfInfo> &gpuPerfInfos) 19206f6ba60Sopenharmony_ci { 19306f6ba60Sopenharmony_ci GpuCounter &gpuCounterInstance = GpuCounter::GetInstance(); 19406f6ba60Sopenharmony_ci 19506f6ba60Sopenharmony_ci for (auto gpuPerfInfo : gpuPerfInfos) { 19606f6ba60Sopenharmony_ci unsigned int gpuCounterBackSize = gpuCounter.size(); 19706f6ba60Sopenharmony_ci gpuCounter.push_back(gpuPerfInfo); 19806f6ba60Sopenharmony_ci unsigned int gpuCounterSize = gpuCounter.size(); 19906f6ba60Sopenharmony_ci if (gpuCounterSize <= gpuCounterBackSize) { 20006f6ba60Sopenharmony_ci LOGE("gpuCounter data len error!"); 20106f6ba60Sopenharmony_ci return -1; 20206f6ba60Sopenharmony_ci } 20306f6ba60Sopenharmony_ci GpuPerfInfo *newData = &gpuCounter[gpuCounterSize - 1]; 20406f6ba60Sopenharmony_ci GpuPerfInfo *backData = &gpuCounter[gpuCounterSize - 2]; 20506f6ba60Sopenharmony_ci long long durationTime = newData->startTime - backData->startTime; 20606f6ba60Sopenharmony_ci 20706f6ba60Sopenharmony_ci // 如果两次数据间隔过短,则舍弃新数据 20806f6ba60Sopenharmony_ci if (durationTime < collectInterval) { 20906f6ba60Sopenharmony_ci LOGE("Start time(%lld, %lld) make duration time(%lld) too short", 21006f6ba60Sopenharmony_ci newData->startTime, backData->startTime, durationTime); 21106f6ba60Sopenharmony_ci gpuCounter.pop_back(); 21206f6ba60Sopenharmony_ci continue; 21306f6ba60Sopenharmony_ci } 21406f6ba60Sopenharmony_ci 21506f6ba60Sopenharmony_ci backData->duration = durationTime; 21606f6ba60Sopenharmony_ci 21706f6ba60Sopenharmony_ci std::ostringstream oss; 21806f6ba60Sopenharmony_ci oss << backData->startTime << "," 21906f6ba60Sopenharmony_ci << backData->duration << "," 22006f6ba60Sopenharmony_ci << backData->gpuActive << "," 22106f6ba60Sopenharmony_ci << backData->drawCalls << "," 22206f6ba60Sopenharmony_ci << backData->primitives << "," 22306f6ba60Sopenharmony_ci << backData->vertexCounts << "," 22406f6ba60Sopenharmony_ci << backData->totalInstruments << "," 22506f6ba60Sopenharmony_ci << backData->gpuLoadPercentage << "," 22606f6ba60Sopenharmony_ci << backData->vertexLoadPercentage << "," 22706f6ba60Sopenharmony_ci << backData->fragmentLoadPercentage << "," 22806f6ba60Sopenharmony_ci << backData->computeLoadPercentage << "," 22906f6ba60Sopenharmony_ci << backData->textureLoadPercentage << "," 23006f6ba60Sopenharmony_ci << backData->memoryReadBandwidth << "," 23106f6ba60Sopenharmony_ci << backData->memoryWriteBandwidth << "," 23206f6ba60Sopenharmony_ci << backData->memoryBandwidthPercentage << ","; 23306f6ba60Sopenharmony_ci gpuCounterInstance.GetGpuCounterData().push_back(oss.str()); 23406f6ba60Sopenharmony_ci gpuCounterInstance.GetGpuCounterSaveReportData().push_back(oss.str()); 23506f6ba60Sopenharmony_ci 23606f6ba60Sopenharmony_ci GetRealTime(backData); 23706f6ba60Sopenharmony_ci } 23806f6ba60Sopenharmony_ci 23906f6ba60Sopenharmony_ci if (gpuPerfInfos[0].remainTime <= restartTime) { 24006f6ba60Sopenharmony_ci LOGI("remain time to restart"); 24106f6ba60Sopenharmony_ci gpuCounterInstance.StartCollect(GpuCounter::GC_RESTART); 24206f6ba60Sopenharmony_ci } 24306f6ba60Sopenharmony_ci return 0; 24406f6ba60Sopenharmony_ci } 24506f6ba60Sopenharmony_ci } 24606f6ba60Sopenharmony_ci}