1/* 2 * Copyright (C) 2022 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 16import { 17 BaseStruct, 18 PerfRender, 19 Rect, 20 RequestMessage, 21} from './ProcedureWorkerCommon'; 22import { TraceRow } from '../../component/trace/base/TraceRow'; 23import { ColorUtils } from '../../component/trace/base/ColorUtils'; 24import { SpSystemTrace } from '../../component/SpSystemTrace'; 25 26export class GpuCounterRender extends PerfRender { 27 renderMainThread( 28 req: { 29 context: CanvasRenderingContext2D, 30 useCache: boolean, 31 type: string, 32 startTime: number, 33 maxValue: number, 34 }, 35 row: TraceRow<GpuCounterStruct> 36 ): void { 37 let filter = row.dataListCache; 38 let startTime = req.startTime; 39 let maxValue = req.maxValue; 40 let type = req.type; 41 gpuCounterChart( 42 filter, 43 startTime, 44 type, 45 TraceRow.range?.startNS ?? 0, 46 TraceRow.range?.endNS ?? 0, 47 TraceRow.range?.totalNS ?? 0, 48 maxValue, 49 row.frame, 50 req.useCache || (TraceRow.range?.refresh ?? false) 51 ); 52 drawGpuCounter(req, filter, row); 53 } 54 55 render(eBPFRequest: RequestMessage, list: Array<unknown>, filter: Array<unknown>, dataList2: Array<unknown>): void { } 56} 57 58function drawGpuCounter( 59 req: { 60 context: CanvasRenderingContext2D, 61 useCache: boolean, 62 type: string, 63 startTime: number, 64 maxValue: number, 65 }, 66 filter: unknown[], 67 row: TraceRow<GpuCounterStruct> 68): void { 69 req.context.beginPath(); 70 let find = false; 71 for (let i = 0; i < filter.length; i++) { 72 let it = filter[i]; 73 if ( 74 //@ts-ignore 75 row.isHover && it.frame && 76 //@ts-ignore 77 row.hoverX >= it.frame.x && 78 //@ts-ignore 79 row.hoverX <= it.frame.x + it.frame.width 80 ) { 81 //@ts-ignore 82 GpuCounterStruct.hoverGpuCounterStruct = it; 83 find = true; 84 } 85 //@ts-ignore 86 GpuCounterStruct.draw(req.context, it); 87 } 88 if (!find && row.isHover) { 89 GpuCounterStruct.hoverGpuCounterStruct = undefined; 90 } 91 req.context.closePath(); 92} 93 94export function gpuCounterChart( 95 dataList: Array<unknown>, 96 startTime: number, 97 type: string, 98 startNS: number, 99 endNS: number, 100 totalNS: number, 101 maxValue: number, 102 frame: Rect, 103 use: boolean 104): void { 105 setFrameGroup(dataList, startTime, type, startNS, endNS, frame, maxValue); 106} 107 108function setFrameGroup(dataList: Array<unknown>, startTime: number, type: string, startNS: number, endNS: number, frame: Rect, maxValue: number): void { 109 let pns = (endNS - startNS) / frame.width; 110 let y = frame.y; 111 for (let i = 0; i < dataList.length; i++) { 112 let it = dataList[i]; 113 //@ts-ignore 114 if ((it.startNS || 0) + (it.dur || 0) - startTime > startNS && (it.startNS || 0) - startTime < endNS) { 115 //@ts-ignore 116 if (!it.frame) { 117 //@ts-ignore 118 it.frame = {}; 119 //@ts-ignore 120 it.frame.y = y; 121 } 122 //@ts-ignore 123 it.frame.height = Math.ceil((it.height / maxValue) * 38) || 1; 124 //@ts-ignore 125 it.startTime = startTime; 126 //@ts-ignore 127 it.type = type; 128 GpuCounterStruct.setFrame(it, startTime, pns, startNS, endNS, frame); 129 } else { 130 //@ts-ignore 131 it.frame = null; 132 } 133 } 134} 135 136export function gpuCounterStructOnClick( 137 clickRowType: string, 138 sp: SpSystemTrace, 139 entry?: GpuCounterStruct, 140): Promise<unknown> { 141 return new Promise((resolve, reject) => { 142 if (clickRowType === TraceRow.ROW_TYPE_GPU_COUNTER && (GpuCounterStruct.hoverGpuCounterStruct || entry)) { 143 GpuCounterStruct.selectGpuCounterStruct = entry || GpuCounterStruct.hoverGpuCounterStruct; 144 sp.traceSheetEL?.displayGpuCounterData(GpuCounterStruct.selectGpuCounterStruct!); 145 sp.timerShaftEL?.modifyFlagList(undefined); 146 reject(new Error()); 147 } else { 148 resolve(null); 149 } 150 }); 151} 152 153export class GpuCounterStruct extends BaseStruct { 154 static hoverGpuCounterStruct: GpuCounterStruct | undefined; 155 static selectGpuCounterStruct: GpuCounterStruct | undefined; 156 startNS: number | undefined; 157 endNS: number | undefined; 158 dur: number | undefined; 159 type: string | undefined; 160 startTime: number | undefined; 161 height: number | undefined; 162 static draw(ctx: CanvasRenderingContext2D, data: GpuCounterStruct): void { 163 if (data.frame) { 164 ctx.fillStyle = ColorUtils.MD_PALETTE[0]; 165 ctx.strokeStyle = ColorUtils.MD_PALETTE[0]; 166 ctx.fillRect(data.frame.x, 40 - data.frame.height, data.frame.width, data.frame.height); 167 if (data.type === GpuCounterStruct.selectGpuCounterStruct?.type && data.startNS === GpuCounterStruct.selectGpuCounterStruct?.startNS) { 168 ctx.strokeStyle = '#000'; 169 ctx.lineWidth = 1; 170 ctx.strokeRect(data.frame.x, 40 - data.frame.height, data.frame.width - 2, data.frame.height); 171 } 172 } 173 } 174 175 static setFrame( 176 eBPFtemNode: unknown, 177 startTime: number, 178 pns: number, 179 startNS: number, 180 endNS: number, 181 frame: unknown 182 ): void { 183 //@ts-ignore 184 if ((eBPFtemNode.startNS - startTime || 0) < startNS) { 185 //@ts-ignore 186 eBPFtemNode.frame.x = 0; 187 } else { 188 //@ts-ignore 189 eBPFtemNode.frame.x = Math.floor((((eBPFtemNode.startNS - startTime) || 0) - startNS) / pns); 190 } 191 //@ts-ignore 192 if ((eBPFtemNode.startNS || 0) + (eBPFtemNode.dur || 0) - startTime > endNS) { 193 //@ts-ignore 194 eBPFtemNode.frame.width = frame.width - eBPFtemNode.frame.x; 195 } else { 196 //@ts-ignore 197 eBPFtemNode.frame.width = Math.ceil(((eBPFtemNode.startNS + eBPFtemNode.dur - startTime) - startNS) / pns - eBPFtemNode.frame.x); 198 } 199 //@ts-ignore 200 if (eBPFtemNode.frame.width < 1) { 201 //@ts-ignore 202 eBPFtemNode.frame.width = 1; 203 } 204 } 205} 206 207export class MaleoonCounterObj { 208 [key: string]: Array<unknown>; 209 gpu_clocks: Array<unknown>; 210 tiler_utilization: Array<unknown>; 211 binning_utilization: Array<unknown>; 212 rendering_utilization: Array<unknown>; 213 compute_utilization: Array<unknown>; 214 drawcall_count: Array<unknown>; 215 vertex_count: Array<unknown>; 216 primitives_count: Array<unknown>; 217 visible_primitives_count: Array<unknown>; 218 compute_invocations_count: Array<unknown>; 219 shader_utilization: Array<unknown>; 220 eu_utilization: Array<unknown>; 221 eu_stall_utilization: Array<unknown>; 222 eu_idle_utilization: Array<unknown>; 223 control_flow_instr_utilization: Array<unknown>; 224 half_float_instr_utilization: Array<unknown>; 225 tu_utilization: Array<unknown>; 226 concurrent_warps: Array<unknown>; 227 instruction_count: Array<unknown>; 228 quads_count: Array<unknown>; 229 texels_count: Array<unknown>; 230 memory_read: Array<unknown>; 231 memory_write: Array<unknown>; 232 memory_traffic: Array<unknown>; 233 constructor() { 234 this.gpu_clocks = []; 235 this.tiler_utilization = []; 236 this.binning_utilization = []; 237 this.rendering_utilization = []; 238 this.compute_utilization = []; 239 240 this.drawcall_count = []; 241 this.vertex_count = []; 242 this.primitives_count = []; 243 this.visible_primitives_count = []; 244 this.compute_invocations_count = []; 245 246 this.shader_utilization = []; 247 this.eu_utilization = []; 248 this.eu_stall_utilization = []; 249 this.eu_idle_utilization = []; 250 this.control_flow_instr_utilization = []; 251 this.half_float_instr_utilization = []; 252 this.tu_utilization = []; 253 254 this.concurrent_warps = []; 255 this.instruction_count = []; 256 this.quads_count = []; 257 this.texels_count = []; 258 259 this.memory_read = []; 260 this.memory_write = []; 261 this.memory_traffic = []; 262 } 263} 264 265export class GpuCounterType { 266 [key: string]: Array<unknown>; 267 'cycle': Array<unknown>; 268 'drawcall': Array<unknown>; 269 'shader_cycle': Array<unknown>; 270 'local_count': Array<unknown>; 271 'local_wr': Array<unknown>; 272 constructor() { 273 this.cycle = []; 274 this.drawcall = []; 275 this.shader_cycle = []; 276 this.local_count = []; 277 this.local_wr = []; 278 } 279} 280