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