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