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 { ColorUtils } from '../../../component/trace/base/ColorUtils'; 17import { HiPerfStruct, PerfRender, type RequestMessage } from '../ProcedureWorkerCommon'; 18 19import { TraceRow } from '../../../component/trace/base/TraceRow'; 20 21export class HiperfReportRender extends PerfRender { 22 renderMainThread(hiPerfReportReq: any, row: TraceRow<HiPerfReportStruct>): void { 23 let list = row.dataList; 24 let filter = row.dataListCache; 25 let groupBy10MS = hiPerfReportReq.scale > 30_000_000; 26 if (list && row.dataList2.length === 0) { 27 row.dataList2 = HiPerfReportStruct.reportGroupBy10MS(list, hiPerfReportReq.intervalPerf); 28 } 29 HiPerfReport( 30 list, 31 row.dataList2, 32 hiPerfReportReq.type!, 33 filter, 34 TraceRow.range?.startNS ?? 0, 35 TraceRow.range?.endNS ?? 0, 36 TraceRow.range?.totalNS ?? 0, 37 row.frame, 38 groupBy10MS, 39 hiPerfReportReq.intervalPerf, 40 hiPerfReportReq.useCache || (TraceRow.range?.refresh ?? false) 41 ); 42 drawHiperfReportRender(hiPerfReportReq, groupBy10MS, filter, row); 43 } 44 45 render(hiPerfReportRequest: RequestMessage, list: Array<any>, filter: Array<any>, dataList2: Array<any>): void {} 46} 47 48function drawHiperfReportRender( 49 hiPerfReportReq: any, 50 groupBy10MS: boolean, 51 filter: HiPerfReportStruct[], 52 row: TraceRow<HiPerfReportStruct> 53) { 54 hiPerfReportReq.context.beginPath(); 55 hiPerfReportReq.context.fillStyle = ColorUtils.FUNC_COLOR[0]; 56 hiPerfReportReq.context.strokeStyle = ColorUtils.FUNC_COLOR[0]; 57 let normalPath = new Path2D(); 58 let specPath = new Path2D(); 59 let offset = groupBy10MS ? 0 : 3; 60 let find = false; 61 for (let re of filter) { 62 HiPerfReportStruct.draw(hiPerfReportReq.context, normalPath, specPath, re, groupBy10MS); 63 if (row.isHover) { 64 if (re.frame && row.hoverX >= re.frame.x - offset && row.hoverX <= re.frame.x + re.frame.width + offset) { 65 HiPerfReportStruct.hoverStruct = re; 66 find = true; 67 } 68 } 69 } 70 if (!find && row.isHover) { 71 HiPerfReportStruct.hoverStruct = undefined; 72 } 73 if (groupBy10MS) { 74 hiPerfReportReq.context.fill(normalPath); 75 } else { 76 hiPerfReportReq.context.stroke(normalPath); 77 HiPerfStruct.drawSpecialPath(hiPerfReportReq.context, specPath); 78 } 79 hiPerfReportReq.context.closePath(); 80} 81 82function setFrameByfilter(startNS: number, endNS: number, frame: any, hiPerfFilters: Array<any>): void { 83 let pns = (endNS - startNS) / frame.width; 84 let y = frame.y; 85 for (let i = 0; i < hiPerfFilters.length; i++) { 86 let hiPerfData = hiPerfFilters[i]; 87 if ((hiPerfData.startNS || 0) + (hiPerfData.dur || 0) > startNS && (hiPerfData.startNS || 0) < endNS) { 88 if (!hiPerfData.frame) { 89 hiPerfData.frame = {}; 90 hiPerfData.frame.y = y; 91 } 92 hiPerfData.frame.height = hiPerfData.height; 93 HiPerfReportStruct.setFrame(hiPerfData, pns, startNS, endNS, frame); 94 } else { 95 hiPerfData.frame = null; 96 } 97 } 98} 99 100function setFrameByArr( 101 groupBy10MS: boolean, 102 arr2: any, 103 arr: Array<any>, 104 hiPerfFilters: Array<any>, 105 startNS: number, 106 endNS: number, 107 frame: any 108): void { 109 let list: Array<any> = groupBy10MS ? arr2 : arr; 110 let pns = (endNS - startNS) / frame.width; 111 let y = frame.y; 112 list 113 .filter((it) => (it.startNS || 0) + (it.dur || 0) > startNS && (it.startNS || 0) < endNS) 114 .map((it) => { 115 if (!it.frame) { 116 it.frame = {}; 117 it.frame.y = y; 118 } 119 it.frame.height = it.height; 120 HiPerfReportStruct.setFrame(it, pns, startNS, endNS, frame); 121 return it; 122 }) 123 .reduce((pre, current, index, arr) => { 124 if (!pre[`${current.frame.x}`]) { 125 pre[`${current.frame.x}`] = []; 126 pre[`${current.frame.x}`].push(current); 127 if (groupBy10MS) { 128 hiPerfFilters.push(current); 129 } else { 130 if (hiPerfFilters.length === 0) { 131 hiPerfFilters.push(current); 132 } 133 if ( 134 hiPerfFilters[hiPerfFilters.length - 1] && 135 Math.abs(current.frame.x - hiPerfFilters[hiPerfFilters.length - 1].frame.x) > 4 136 ) { 137 hiPerfFilters.push(current); 138 } 139 } 140 } 141 return pre; 142 }, {}); 143} 144 145export function HiPerfReport( 146 arr: Array<any>, 147 arr2: any, 148 type: string, 149 hiPerfFilters: Array<any>, 150 startNS: number, 151 endNS: number, 152 totalNS: number, 153 frame: any, 154 groupBy10MS: boolean, 155 intervalPerf: number, 156 use: boolean 157): void { 158 if (use && hiPerfFilters.length > 0) { 159 setFrameByfilter(endNS, startNS, frame, hiPerfFilters); 160 return; 161 } 162 hiPerfFilters.length = 0; 163 if (arr) { 164 setFrameByArr(groupBy10MS, arr2, arr, hiPerfFilters, startNS, endNS, frame); 165 } 166} 167 168export class HiPerfReportStruct extends HiPerfStruct { 169 static hoverStruct: HiPerfReportStruct | undefined; 170 static selectStruct: HiPerfReportStruct | undefined; 171 172 static reportGroupBy10MS(array: Array<any>, intervalPerf: number): Array<any> { 173 let obj = array 174 .map((it) => { 175 it.timestamp_group = Math.trunc(it.startNS / 1_000_000_0) * 1_000_000_0; 176 return it; 177 }) 178 .reduce((pre, current) => { 179 (pre[current['timestamp_group']] = pre[current['timestamp_group']] || []).push(current); 180 return pre; 181 }, {}); 182 let reportArr: any[] = []; 183 let max = 0; 184 for (let aKey in obj) { 185 let sum = obj[aKey].reduce((pre: any, cur: any) => { 186 return pre + cur.event_count; 187 }, 0); 188 if (sum > max) max = sum; 189 let ns = parseInt(aKey); 190 reportArr.push({ 191 startNS: ns, 192 dur: 1_000_000_0, 193 height: 0, 194 sum: sum, 195 }); 196 } 197 reportArr.map((it) => { 198 it.height = Math.floor((40 * it.sum) / max); 199 return it; 200 }); 201 return reportArr; 202 } 203} 204