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 dataFilterHandler, 19 drawLoading, 20 isFrameContainPoint, 21 ns2x, 22 drawLines, 23 Render, 24 drawFlagLine, 25 RequestMessage, 26 drawSelection, drawLoadingFrame, 27} from '../ProcedureWorkerCommon'; 28import { ColorUtils } from '../../../component/trace/base/ColorUtils'; 29import { TraceRow } from '../../../component/trace/base/TraceRow'; 30import { convertJSON } from '../../logic-worker/ProcedureLogicWorkerCommon'; 31import {SpSystemTrace} from "../../../component/SpSystemTrace"; 32 33export class CpuFreqLimitRender extends Render { 34 renderMainThread( 35 cpuFreqLimitReq: { 36 useCache: boolean; 37 context: CanvasRenderingContext2D; 38 cpu: number; 39 type: string; 40 maxFreq: number; 41 maxFreqName: string; 42 }, 43 row: TraceRow<CpuFreqLimitsStruct> 44 ) { 45 let list = row.dataList; 46 let filter = row.dataListCache; 47 dataFilterHandler(list, filter, { 48 startKey: 'startNs', 49 durKey: 'dur', 50 startNS: TraceRow.range?.startNS ?? 0, 51 endNS: TraceRow.range?.endNS ?? 0, 52 totalNS: TraceRow.range?.totalNS ?? 0, 53 frame: row.frame, 54 paddingTop: 5, 55 useCache: cpuFreqLimitReq.useCache || !(TraceRow.range?.refresh ?? false), 56 }); 57 drawLoadingFrame(cpuFreqLimitReq.context, filter, row); 58 cpuFreqLimitReq.context.beginPath(); 59 let maxFreq = cpuFreqLimitReq.maxFreq; 60 let maxFreqName = cpuFreqLimitReq.maxFreqName; 61 if (row.isHover) { 62 for (let re of filter) { 63 if (re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { 64 CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = re; 65 break; 66 } 67 } 68 } 69 for (let re of filter) { 70 CpuFreqLimitsStruct.draw(cpuFreqLimitReq.context, re, maxFreq); 71 } 72 cpuFreqLimitReq.context.closePath(); 73 let s = maxFreqName; 74 let textMetrics = cpuFreqLimitReq.context.measureText(s); 75 cpuFreqLimitReq.context.globalAlpha = 0.8; 76 cpuFreqLimitReq.context.fillStyle = '#f0f0f0'; 77 cpuFreqLimitReq.context.fillRect(0, 5, textMetrics.width + 8, 18); 78 cpuFreqLimitReq.context.globalAlpha = 1; 79 cpuFreqLimitReq.context.fillStyle = '#333'; 80 cpuFreqLimitReq.context.textBaseline = 'middle'; 81 cpuFreqLimitReq.context.fillText(s, 4, 5 + 9); 82 } 83} 84export function CpuFreqLimitsStructOnClick(clickRowType: string, sp: SpSystemTrace) { 85 return new Promise((resolve, reject) => { 86 if (clickRowType === TraceRow.ROW_TYPE_CPU_FREQ_LIMIT && CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct) { 87 CpuFreqLimitsStruct.selectCpuFreqLimitsStruct = CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct; 88 sp.traceSheetEL?.displayFreqLimitData(); 89 sp.timerShaftEL?.modifyFlagList(undefined); 90 reject(); 91 }else{ 92 resolve(null); 93 } 94 }); 95} 96export class CpuFreqLimitsStruct extends BaseStruct { 97 static hoverCpuFreqLimitsStruct: CpuFreqLimitsStruct | undefined; 98 static selectCpuFreqLimitsStruct: CpuFreqLimitsStruct | undefined; 99 static minAlpha = 0.4; 100 static maxAlpha = 0.8; 101 startNs: number | undefined; 102 dur: number = 0; 103 max: number | undefined; 104 min: number | undefined; 105 cpu: number = 0; 106 107 static draw(ctx: CanvasRenderingContext2D, data: CpuFreqLimitsStruct, maxFreq: number) { 108 if (data.frame) { 109 let width = data.frame.width || 0; 110 let drawMaxHeight: number = Math.floor(((data.max || 0) * (data.frame.height || 0)) / maxFreq); 111 let drawMinHeight: number = Math.floor(((data.min || 0) * (data.frame.height || 0)) / maxFreq); 112 let index = data.cpu || 0; 113 index += 2; 114 ctx.fillStyle = ColorUtils.colorForTid(index); 115 ctx.strokeStyle = ColorUtils.colorForTid(index); 116 if ( 117 data === CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct || 118 data === CpuFreqLimitsStruct.selectCpuFreqLimitsStruct 119 ) { 120 ctx.lineWidth = 1; 121 ctx.globalAlpha = this.minAlpha; 122 this.drawArcLine(ctx, data, drawMaxHeight, drawMaxHeight - drawMinHeight); 123 ctx.globalAlpha = this.maxAlpha; 124 this.drawArcLine(ctx, data, drawMinHeight, drawMinHeight); 125 } else { 126 ctx.globalAlpha = this.minAlpha; 127 ctx.lineWidth = 1; 128 ctx.fillRect( 129 data.frame.x, 130 data.frame.y + data.frame.height - drawMaxHeight, 131 width, 132 drawMaxHeight - drawMinHeight 133 ); 134 ctx.globalAlpha = this.maxAlpha; 135 ctx.fillRect(data.frame.x, data.frame.y + data.frame.height - drawMinHeight, width, drawMinHeight); 136 } 137 } 138 ctx.globalAlpha = 1.0; 139 ctx.lineWidth = 1; 140 } 141 142 static drawArcLine( 143 ctx: CanvasRenderingContext2D, 144 data: CpuFreqLimitsStruct, 145 yStartHeight: number, 146 drawHeight: number 147 ) { 148 if (data.frame) { 149 let width = data.frame.width || 0; 150 ctx.fillRect(data.frame.x, data.frame.y + data.frame.height - yStartHeight, width, drawHeight); 151 ctx.globalAlpha = this.maxAlpha; 152 ctx.beginPath(); 153 ctx.arc(data.frame.x, data.frame.y + data.frame.height - yStartHeight, 3, 0, 2 * Math.PI, true); 154 ctx.fill(); 155 ctx.stroke(); 156 ctx.beginPath(); 157 ctx.moveTo(data.frame.x + 3, data.frame.y + data.frame.height - yStartHeight); 158 ctx.lineWidth = 3; 159 ctx.lineTo(data.frame.x + width, data.frame.y + data.frame.height - yStartHeight); 160 ctx.stroke(); 161 } 162 } 163 164 static setFreqLimitFrame( 165 freqLimitNode: any, 166 padding: number, 167 startNS: number, 168 endNS: number, 169 totalNS: number, 170 frame: any 171 ) { 172 let x1: number, x2: number; 173 if ((freqLimitNode.startNs || 0) < startNS) { 174 x1 = 0; 175 } else { 176 x1 = ns2x(freqLimitNode.startNs || 0, startNS, endNS, totalNS, frame); 177 } 178 if ((freqLimitNode.startNs || 0) + (freqLimitNode.dur || 0) > endNS) { 179 x2 = frame.width; 180 } else { 181 x2 = ns2x((freqLimitNode.startNs || 0) + (freqLimitNode.dur || 0), startNS, endNS, totalNS, frame); 182 } 183 let cpuFreqLimitsGetV: number = x2 - x1 <= 1 ? 1 : x2 - x1; 184 if (!freqLimitNode.frame) { 185 freqLimitNode.frame = {}; 186 } 187 freqLimitNode.frame.x = Math.floor(x1); 188 freqLimitNode.frame.y = frame.y + padding; 189 freqLimitNode.frame.width = Math.ceil(cpuFreqLimitsGetV); 190 freqLimitNode.frame.height = Math.floor(frame.height - padding * 2); 191 } 192} 193