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 { hiPerf, HiPerfStruct, PerfRender, RequestMessage } from '../ProcedureWorkerCommon'; 18import { TraceRow } from '../../../component/trace/base/TraceRow'; 19 20export class HiperfEventRender extends PerfRender { 21 renderMainThread(hiPerfEventReq: any, row: TraceRow<HiPerfEventStruct>): void { 22 let list = row.dataList; 23 let list2 = row.dataList2; 24 let filter = row.dataListCache; 25 let groupBy10MS = hiPerfEventReq.scale > 30_000_000; 26 if (list && row.dataList2.length === 0) { 27 row.dataList2 = HiPerfEventStruct.eventGroupBy10MS(list, hiPerfEventReq.intervalPerf, hiPerfEventReq.type); 28 } 29 hiPerf( 30 list, 31 list2, 32 filter, 33 TraceRow.range?.startNS ?? 0, 34 TraceRow.range?.endNS ?? 0, 35 row.frame, 36 groupBy10MS, 37 hiPerfEventReq.useCache || (TraceRow.range?.refresh ?? false) 38 ); 39 drawHiPerfEvent(hiPerfEventReq, groupBy10MS, filter, row); 40 } 41 42 render(hiPerfEventRequest: RequestMessage, list: Array<any>, filter: Array<any>, dataList2: Array<any>): void {} 43} 44 45function drawHiPerfEvent( 46 hiPerfEventReq: any, 47 groupBy10MS: boolean, 48 filter: HiPerfEventStruct[], 49 row: TraceRow<HiPerfEventStruct> 50) { 51 hiPerfEventReq.context.beginPath(); 52 hiPerfEventReq.context.fillStyle = ColorUtils.FUNC_COLOR[0]; 53 hiPerfEventReq.context.strokeStyle = ColorUtils.FUNC_COLOR[0]; 54 let offset = groupBy10MS ? 0 : 3; 55 let normalPath = new Path2D(); 56 let specPath = new Path2D(); 57 let find = false; 58 for (let re of filter) { 59 HiPerfEventStruct.draw(hiPerfEventReq.context, normalPath, specPath, re, groupBy10MS); 60 if (row.isHover) { 61 if (re.frame && row.hoverX >= re.frame.x - offset && row.hoverX <= re.frame.x + re.frame.width + offset) { 62 HiPerfEventStruct.hoverStruct = re; 63 find = true; 64 } 65 } 66 } 67 if (!find && row.isHover) { 68 HiPerfEventStruct.hoverStruct = undefined; 69 } 70 if (groupBy10MS) { 71 hiPerfEventReq.context.fill(normalPath); 72 } else { 73 hiPerfEventReq.context.stroke(normalPath); 74 HiPerfStruct.drawSpecialPath(hiPerfEventReq.context, specPath); 75 } 76 let maxEvent = HiPerfEventStruct.maxEvent!.get(hiPerfEventReq.type!) || 0; 77 let textMetrics = hiPerfEventReq.context.measureText(maxEvent); 78 hiPerfEventReq.context.globalAlpha = 0.8; 79 hiPerfEventReq.context.fillStyle = '#f0f0f0'; 80 hiPerfEventReq.context.fillRect(0, 5, textMetrics.width + 8, 18); 81 hiPerfEventReq.context.globalAlpha = 1; 82 hiPerfEventReq.context.fillStyle = '#333'; 83 hiPerfEventReq.context.textBaseline = 'middle'; 84 hiPerfEventReq.context.fillText(maxEvent, 4, 5 + 9); 85 hiPerfEventReq.context.stroke(); 86 hiPerfEventReq.context.closePath(); 87} 88 89export class HiPerfEventStruct extends HiPerfStruct { 90 static hoverStruct: HiPerfEventStruct | undefined; 91 static selectStruct: HiPerfEventStruct | undefined; 92 93 static maxEvent: Map<string, number> | undefined = new Map(); 94 sum: number | undefined; 95 max: number | undefined; 96 97 static eventGroupBy10MS(array: Array<any>, intervalPerf: number, type: string): Array<any> { 98 let obj = array 99 .map((hiPerfDataItem) => { 100 hiPerfDataItem.timestamp_group = Math.trunc(hiPerfDataItem.startNS / 1_000_000_0) * 1_000_000_0; 101 return hiPerfDataItem; 102 }) 103 .reduce((pre, current) => { 104 (pre[current['timestamp_group']] = pre[current['timestamp_group']] || []).push(current); 105 return pre; 106 }, {}); 107 let eventArr: any[] = []; 108 let max = 0; 109 for (let aKey in obj) { 110 let sum = obj[aKey].reduce((pre: any, cur: any) => { 111 return pre + cur.event_count; 112 }, 0); 113 if (sum > max) max = sum; 114 let ns = parseInt(aKey); 115 eventArr.push({ 116 startNS: ns, 117 dur: 1_000_000_0, 118 height: 0, 119 sum: sum, 120 }); 121 } 122 if (typeof HiPerfEventStruct.maxEvent!.get(type) === 'undefined') { 123 HiPerfEventStruct.maxEvent!.set(type, max); 124 } 125 eventArr.map((it) => { 126 it.height = Math.floor((40 * it.sum) / max); 127 it.max = max; 128 return it; 129 }); 130 return eventArr; 131 } 132} 133