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 { BaseStruct, dataFilterHandler, isFrameContainPoint, Render, RequestMessage } from './ProcedureWorkerCommon'; 18import { TraceRow } from '../../component/trace/base/TraceRow'; 19import { SpSegmentationChart } from '../../component/chart/SpSegmentationChart'; 20import { drawLoadingFrame } from './ProcedureWorkerCommon'; 21import { ns2x, Rect } from './ProcedureWorkerCommon'; 22import { Flag } from '../../component/trace/timer-shaft/Flag'; 23export class FreqExtendRender extends Render { 24 renderMainThread( 25 freqReq: { 26 context: CanvasRenderingContext2D; 27 useCache: boolean; 28 type: string; 29 }, 30 row: TraceRow<CpuFreqExtendStruct> 31 ): void { 32 let freqExtendList = row.dataList; 33 let freqExtendFilter = row.dataListCache; 34 dataFilterHandler(freqExtendList, freqExtendFilter, { 35 startKey: 'startNS', 36 durKey: 'dur', 37 startNS: TraceRow.range?.startNS ?? 0, 38 endNS: TraceRow.range?.endNS ?? 0, 39 totalNS: TraceRow.range?.totalNS ?? 0, 40 frame: row.frame, 41 paddingTop: 5, 42 useCache: freqReq.useCache || !(TraceRow.range?.refresh ?? false), 43 }); 44 drawLoadingFrame(freqReq.context, freqExtendFilter, row); 45 freqReq.context.beginPath(); 46 let find = false; 47 // tab页点击周期 48 if (SpSegmentationChart.tabHoverObj && SpSegmentationChart.tabHoverObj.key !== '' && SpSegmentationChart.tabHoverObj.key === freqReq.type) { 49 // 鼠标不在tab页,清空高亮 50 if (!SpSegmentationChart.trace.isMousePointInSheet) { 51 SpSegmentationChart.tabHoverObj = { key: '', cycle: -1 }; 52 CpuFreqExtendStruct.hoverStruct = undefined; 53 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = undefined; 54 find = false; 55 } 56 // tab页点击周期对应泳道 57 if (SpSegmentationChart.tabHoverObj.key === freqReq.type) { 58 for (let re of freqExtendFilter) { 59 if (!row.isHover && re.cycle === SpSegmentationChart.tabHoverObj.cycle) { 60 CpuFreqExtendStruct.hoverStruct = re; 61 find = true; 62 } 63 CpuFreqExtendStruct.draw(freqReq.context, re, freqReq.type, row); 64 } 65 // dur太小,从datalist里面找 66 if (!find) { 67 let hoverData = freqExtendList.filter(v => { 68 return v.cycle === SpSegmentationChart.tabHoverObj.cycle; 69 })[0]; 70 let pointX: number = ns2x( 71 hoverData.startNS || 0, 72 TraceRow.range!.startNS, 73 TraceRow.range!.endNS, 74 TraceRow.range!.totalNS, 75 new Rect(0, 0, TraceRow.FRAME_WIDTH, 0) 76 ); 77 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = new Flag( 78 Math.floor(pointX), 79 0, 80 0, 81 0, 82 hoverData.startNS, 83 '#666666', 84 '', 85 true, 86 '' 87 ); 88 } 89 } else { 90 for (let re of freqExtendFilter) { 91 CpuFreqExtendStruct.draw(freqReq.context, re, freqReq.type, row); 92 } 93 } 94 // 正常悬浮或者tab页取消点击周期 95 } else { 96 // 鼠标悬浮色块 97 for (let re of freqExtendFilter) { 98 if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { 99 if (SpSegmentationChart.tabHoverObj) { 100 // @ts-ignore 101 SpSegmentationChart.tabHoverObj = { key: freqReq.type, cycle: re.cycle }; 102 } 103 CpuFreqExtendStruct.hoverStruct = re; 104 find = true; 105 } 106 CpuFreqExtendStruct.draw(freqReq.context, re, freqReq.type, row); 107 } 108 // 取消点击周期 109 if ((row.isHover && !find) || (!row.isHover && SpSegmentationChart.tabHoverObj && SpSegmentationChart.tabHoverObj.key !== '' && 110 freqReq.type === SpSegmentationChart.tabHoverObj.key) || 111 (SpSegmentationChart.trace.isMousePointInSheet && SpSegmentationChart.tabHoverObj && SpSegmentationChart.tabHoverObj.key === '') 112 ) { 113 CpuFreqExtendStruct.hoverStruct = undefined; 114 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = undefined; 115 SpSegmentationChart.tabHoverObj = { key: '', cycle: -1 }; 116 } 117 } 118 freqReq.context.closePath(); 119 } 120} 121 122export class CpuFreqExtendStruct extends BaseStruct { 123 static hoverStruct: CpuFreqExtendStruct | undefined; 124 static cpuMaxValue: number = 0; 125 static gpuMaxValue: number = 0; 126 static schedMaxValue: number = 0; 127 static cpuCycle: number = -1; 128 static gpuCycle: number = -1; 129 static schedCycle: number = -1; 130 static isTabHover: boolean = false; 131 static hoverType: string = ''; 132 static tabCycle: number = -1; 133 static selectCpuFreqStruct: CpuFreqExtendStruct | undefined; 134 value: number = 0; 135 startNS: number = 0; 136 dur: number | undefined; //自补充,数据库没有返回 137 cycle: number | undefined; 138 colorIndex: number = 0; 139 140 static draw(freqContext: CanvasRenderingContext2D, data: CpuFreqExtendStruct, type: string, row: TraceRow<CpuFreqExtendStruct>): void { 141 if (data.frame) { 142 let width = data.frame.width || 0; 143 let index = data.colorIndex || 0; 144 index += 2; 145 let color = ColorUtils.colorForTid(index); 146 if (type === 'SCHED-SWITCH') { 147 color = '#3ced33'; 148 } 149 freqContext.fillStyle = color; 150 if ( 151 data === CpuFreqExtendStruct.hoverStruct 152 ) { 153 freqContext.globalAlpha = 1.0; 154 let drawHeight: number = Math.floor( 155 ((data.value || 0) * (data.frame.height || 0) * 1.0) / (type === 'CPU-FREQ' 156 ? CpuFreqExtendStruct.cpuMaxValue : type === 'GPU-FREQ' 157 ? CpuFreqExtendStruct.gpuMaxValue : CpuFreqExtendStruct.schedMaxValue) 158 ); 159 if (drawHeight < 1) { 160 drawHeight = 1; 161 } 162 freqContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width < 1 ? 1 : width, drawHeight); 163 let pointX: number = ns2x( 164 data.startNS || 0, 165 TraceRow.range!.startNS, 166 TraceRow.range!.endNS, 167 TraceRow.range!.totalNS, 168 new Rect(0, 0, TraceRow.FRAME_WIDTH, 0) 169 ); 170 SpSegmentationChart.trace.traceSheetEL!.systemLogFlag = new Flag( 171 Math.floor(pointX), 172 0, 173 0, 174 0, 175 data.startNS, 176 '#666666', 177 '', 178 true, 179 '' 180 ); 181 } else { 182 freqContext.globalAlpha = 0.6; 183 freqContext.lineWidth = 1; 184 let drawHeight: number = Math.floor( 185 ((data.value || 0) * (data.frame.height || 0)) / (type === 'CPU-FREQ' 186 ? CpuFreqExtendStruct.cpuMaxValue : type === 'GPU-FREQ' 187 ? CpuFreqExtendStruct.gpuMaxValue : CpuFreqExtendStruct.schedMaxValue) 188 ); 189 if (drawHeight < 1) { 190 drawHeight = 1; 191 } 192 freqContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight, width < 1 ? 1 : width, drawHeight); 193 } 194 } 195 } 196} 197