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 drawFlagLine, 19 drawLines, 20 drawLoading, drawSelection, 21 drawWakeUp, ns2x, PerfRender, Render, 22 RequestMessage 23} from "./ProcedureWorkerCommon.js"; 24import {FileSysChartStruct} from "./ProcedureWorkerFileSystem.js"; 25import {FuncStruct} from "./ProcedureWorkerFunc.js"; 26import {SpFreqChart} from "../../component/chart/SpFreqChart.js"; 27 28export class CpuStateRender extends PerfRender{ 29 render(req:RequestMessage,list:Array<any>,filter:Array<any>,dataList2:Array<any>){ 30 if (req.lazyRefresh) { 31 this.cpuState(list,dataList2,req.type!, filter,req.params.cpu,req.startNS, req.endNS, req.totalNS, req.frame, req.useCache || !req.range.refresh); 32 } else { 33 if (!req.useCache) { 34 this.cpuState(list,dataList2,req.type!, filter,req.params.cpu,req.startNS, req.endNS, req.totalNS, req.frame, false); 35 } 36 } 37 CpuStateStruct.hoverStateStruct = undefined; 38 if (req.canvas) { 39 req.context.clearRect(0, 0, req.frame.width, req.frame.height); 40 if (filter.length > 0 && !req.range.refresh && !req.useCache && req.lazyRefresh) { 41 drawLoading(req.context, req.startNS, req.endNS, req.totalNS, req.frame, filter[0].startTs, filter[filter.length - 1].startTs + filter[filter.length - 1].dur) 42 } 43 req.context.beginPath(); 44 drawLines(req.context, req.xs, req.frame.height, req.lineColor); 45 if (req.isHover) { 46 let offset = 3; 47 for (let re of filter) { 48 if (re.frame && req.hoverX >= re.frame.x - offset && req.hoverX <= re.frame.x + re.frame.width + offset) { 49 CpuStateStruct.hoverStateStruct = re; 50 break; 51 } 52 } 53 } 54 CpuStateStruct.selectStateStruct = req.params.selectStateStruct; 55 req.context.font = "11px sans-serif"; 56 req.context.fillStyle = req.chartColor; 57 req.context.strokeStyle = req.chartColor; 58 req.context.globalAlpha = 0.6; 59 let path = new Path2D(); 60 for (let re of filter) { 61 CpuStateStruct.draw(req.context, path,re); 62 } 63 req.context.fill(path); 64 drawSelection(req.context, req.params); 65 drawWakeUp(req.context, req.wakeupBean, req.startNS, req.endNS, req.totalNS, req.frame); 66 drawFlagLine(req.context, req.flagMoveInfo, req.flagSelectedInfo, req.startNS, req.endNS, req.totalNS, req.frame, req.slicesTime); 67 } 68 let msg = { 69 id: req.id, 70 type: req.type, 71 results: req.canvas ? undefined : filter, 72 hover: CpuStateStruct.hoverStateStruct 73 } 74 self.postMessage(msg); 75 } 76 77 cpuState(arr: Array<any>, arr2: any, type: string,res: Array<any>, cpu:number,startNS: number, endNS: number, totalNS: number, frame: any,use:boolean) { 78 if (use && res.length > 0) { 79 for (let i = 0, len = res.length; i < len; i++) { 80 if ((res[i].startTs || 0) + (res[i].dur || 0) >= startNS && (res[i].startTs || 0) <= endNS) { 81 CpuStateStruct.setFrame(res[i], 5, startNS, endNS, totalNS, frame) 82 } else { 83 res[i].frame = null; 84 } 85 } 86 return; 87 } 88 res.length = 0; 89 if (arr) { 90 let list: Array<any> = []; 91 if (arr2[type] && arr2[type].length > 0) { 92 list = arr2[type]; 93 } else { 94 list = this.getList(arr,endNS,cpu); 95 arr2[type] = list; 96 } 97 let groups = list.filter(it => (it.startTs || 0) + (it.dur || 0) >= startNS && (it.startTs || 0) <= endNS).map(it => { 98 CpuStateStruct.setFrame(it, 5, startNS, endNS, totalNS, frame) 99 return it; 100 }).reduce((pre, current, index, arr) => { 101 (pre[`${current.frame.x}`] = pre[`${current.frame.x}`] || []).push(current); 102 return pre; 103 }, {}); 104 Reflect.ownKeys(groups).map((kv => { 105 res.push(groups[kv].sort((a: any, b: any) => b.frame.width - a.frame.width)[0]); 106 res.push(groups[kv].sort((a: any, b: any) => b.frame.height - a.frame.height)[0]); 107 })); 108 } 109 } 110 111 getList(arr:Array<any>,endNS:number,cpu:number):Array<any>{ 112 let heights = [4,12,21,30] 113 for (let i = 0, len = arr.length; i < len; i++) { 114 let it = arr[i]; 115 it.height = heights[it.value] 116 it.cpu = cpu; 117 if (i === arr.length - 1) { 118 it.dur = (endNS || 0) - (it.startTs || 0) 119 } else { 120 it.dur = (arr[i + 1].startTs || 0) - (it.startTs || 0) 121 } 122 } 123 return arr; 124 } 125} 126 127export class CpuStateStruct extends BaseStruct { 128 static hoverStateStruct:any; 129 static selectStateStruct:any; 130 dur: number | undefined 131 value: string | undefined 132 startTs: number | undefined 133 height: number | undefined 134 cpu:number | undefined 135 136 static draw(ctx: CanvasRenderingContext2D,path:Path2D,data: CpuStateStruct) { 137 if (data.frame) { 138 if (data.startTs === CpuStateStruct.hoverStateStruct?.startTs || data.startTs === CpuStateStruct.selectStateStruct?.startTs) { 139 path.rect(data.frame.x, 35 - (data.height || 0), data.frame.width, data.height || 0) 140 ctx.lineWidth = 1; 141 ctx.globalAlpha = 1.0; 142 ctx.beginPath() 143 ctx.arc(data.frame.x, 35 - (data.height || 0), 3, 0, 2 * Math.PI, true) 144 ctx.stroke() 145 ctx.beginPath() 146 ctx.moveTo(data.frame.x + 3, 35 - (data.height || 0)); 147 ctx.lineWidth = 3; 148 ctx.lineTo(data.frame.x + data.frame.width, 35 - (data.height || 0)) 149 ctx.stroke(); 150 ctx.lineWidth = 1; 151 ctx.globalAlpha = 0.6; 152 ctx.fillRect(data.frame.x, 35 - (data.height || 0), data.frame.width, data.height || 0) 153 }else{ 154 ctx.globalAlpha = 0.6; 155 path.rect(data.frame.x, 35 - (data.height || 0), data.frame.width, data.height || 0) 156 } 157 } 158 } 159 160 static setFrame(node: any, padding: number, startNS: number, endNS: number,totalNS:number, frame: any) { 161 let x1: number, x2: number; 162 if ((node.startTs || 0) < startNS) { 163 x1 = 0; 164 } else { 165 x1 = ns2x((node.startTs || 0), startNS, endNS, totalNS, frame); 166 } 167 if ((node.startTs || 0) + (node.dur || 0) > endNS) { 168 x2 = frame.width; 169 } else { 170 x2 = ns2x((node.startTs || 0) + (node.dur || 0), startNS, endNS, totalNS, frame); 171 } 172 let getV: number = x2 - x1 <= 1 ? 1 : x2 - x1; 173 if (!node.frame) { 174 node.frame = {}; 175 } 176 node.frame.x = Math.ceil(x1); 177 node.frame.y = frame.y + padding; 178 node.frame.width = Math.floor(getV); 179 node.frame.height = node.height; 180 } 181} 182