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 { 18 BaseStruct, 19 dataFilterHandler, 20 isFrameContainPoint, 21 ns2x, 22 RequestMessage, 23 Render, 24 drawLoadingFrame, 25 Rect, 26} from './ProcedureWorkerCommon'; 27import { TraceRow } from '../../component/trace/base/TraceRow'; 28 29export class CpuAbilityRender extends Render { 30 renderMainThread( 31 req: { 32 context: CanvasRenderingContext2D; 33 useCache: boolean; 34 type: string; 35 maxCpuUtilization: number; 36 maxCpuUtilizationName: string; 37 }, 38 cpuAbilityRow: TraceRow<CpuAbilityMonitorStruct> 39 ): void { 40 let cpuAbilityList = cpuAbilityRow.dataList; 41 let cpuAbilityFilter = cpuAbilityRow.dataListCache; 42 dataFilterHandler(cpuAbilityList, cpuAbilityFilter, { 43 startKey: 'startNS', 44 durKey: 'dur', 45 startNS: TraceRow.range?.startNS ?? 0, 46 endNS: TraceRow.range?.endNS ?? 0, 47 totalNS: TraceRow.range?.totalNS ?? 0, 48 frame: cpuAbilityRow.frame, 49 paddingTop: 5, 50 useCache: req.useCache || !(TraceRow.range?.refresh ?? false), 51 }); 52 let find = false; 53 drawLoadingFrame(req.context, cpuAbilityRow.dataListCache, cpuAbilityRow); 54 req.context.beginPath(); 55 for (let re of cpuAbilityFilter) { 56 CpuAbilityMonitorStruct.draw(req.context, re, req.maxCpuUtilization, cpuAbilityRow.isHover); 57 if ( 58 cpuAbilityRow.isHover && 59 re.frame && 60 isFrameContainPoint(re.frame, cpuAbilityRow.hoverX, cpuAbilityRow.hoverY) 61 ) { 62 CpuAbilityMonitorStruct.hoverCpuAbilityStruct = re; 63 find = true; 64 } 65 } 66 if (!find && cpuAbilityRow.isHover) { 67 CpuAbilityMonitorStruct.hoverCpuAbilityStruct = undefined; 68 } 69 req.context.closePath(); 70 let textMetrics = req.context.measureText(req.maxCpuUtilizationName); 71 req.context.globalAlpha = 0.8; 72 req.context.fillStyle = '#f0f0f0'; 73 req.context.fillRect(0, 5, textMetrics.width + 8, 18); 74 req.context.globalAlpha = 1; 75 req.context.fillStyle = '#333'; 76 req.context.textBaseline = 'middle'; 77 req.context.fillText(req.maxCpuUtilizationName, 4, 5 + 9); 78 } 79 80 render(req: unknown, list: Array<unknown>, filter: Array<unknown>): void {} 81} 82 83export class CpuAbilityMonitorStruct extends BaseStruct { 84 static maxCpuUtilization: number = 0; 85 static maxCpuUtilizationName: string = '0 %'; 86 static hoverCpuAbilityStruct: CpuAbilityMonitorStruct | undefined; 87 static selectCpuAbilityStruct: CpuAbilityMonitorStruct | undefined; 88 89 type: number | undefined; 90 value: number | undefined; 91 startNS: number | undefined; 92 dur: number | undefined; //自补充,数据库没有返回 93 94 static draw( 95 cpuAbilityContext2D: CanvasRenderingContext2D, 96 cpuAbilityData: CpuAbilityMonitorStruct, 97 maxCpuUtilization: number, 98 isHover: boolean 99 ): void { 100 if (cpuAbilityData.frame) { 101 let width = cpuAbilityData.frame.width || 0; 102 let index = 2; 103 cpuAbilityContext2D.fillStyle = ColorUtils.colorForTid(index); 104 cpuAbilityContext2D.strokeStyle = ColorUtils.colorForTid(index); 105 if (cpuAbilityData.startNS === CpuAbilityMonitorStruct.hoverCpuAbilityStruct?.startNS && isHover) { 106 cpuAbilityContext2D.lineWidth = 1; 107 cpuAbilityContext2D.globalAlpha = 0.6; 108 let drawHeight: number = Math.floor( 109 ((cpuAbilityData.value || 0) * (cpuAbilityData.frame.height || 0) * 1.0) / maxCpuUtilization 110 ); 111 let y = cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4; 112 cpuAbilityContext2D.fillRect(cpuAbilityData.frame.x, y, width, drawHeight); 113 cpuAbilityContext2D.beginPath(); 114 cpuAbilityContext2D.arc(cpuAbilityData.frame.x, y, 3, 0, 2 * Math.PI, true); 115 cpuAbilityContext2D.fill(); 116 cpuAbilityContext2D.globalAlpha = 1.0; 117 cpuAbilityContext2D.stroke(); 118 cpuAbilityContext2D.beginPath(); 119 cpuAbilityContext2D.moveTo(cpuAbilityData.frame.x + 3, y); 120 cpuAbilityContext2D.lineWidth = 3; 121 cpuAbilityContext2D.lineTo(cpuAbilityData.frame.x + width, y); 122 cpuAbilityContext2D.stroke(); 123 } else { 124 cpuAbilityContext2D.globalAlpha = 0.6; 125 cpuAbilityContext2D.lineWidth = 1; 126 let drawHeight: number = Math.floor( 127 ((cpuAbilityData.value || 0) * (cpuAbilityData.frame.height || 0)) / maxCpuUtilization 128 ); 129 let rectY = cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4; 130 cpuAbilityContext2D.fillRect(cpuAbilityData.frame.x, rectY, width, drawHeight); 131 } 132 } 133 cpuAbilityContext2D.globalAlpha = 1.0; 134 cpuAbilityContext2D.lineWidth = 1; 135 } 136 137 static setCpuAbilityFrame( 138 cpuAbilityNode: CpuAbilityMonitorStruct, 139 padding: number, 140 startNS: number, 141 endNS: number, 142 totalNS: number, 143 frame: Rect 144 ): void { 145 let cpuAbilityStartPointX: number; 146 let cpuAbilityEndPointX: number; 147 148 if ((cpuAbilityNode.startNS || 0) < startNS) { 149 cpuAbilityStartPointX = 0; 150 } else { 151 cpuAbilityStartPointX = ns2x(cpuAbilityNode.startNS || 0, startNS, endNS, totalNS, frame); 152 } 153 if ((cpuAbilityNode.startNS || 0) + (cpuAbilityNode.dur || 0) > endNS) { 154 cpuAbilityEndPointX = frame.width; 155 } else { 156 cpuAbilityEndPointX = ns2x( 157 (cpuAbilityNode.startNS || 0) + (cpuAbilityNode.dur || 0), 158 startNS, 159 endNS, 160 totalNS, 161 frame 162 ); 163 } 164 let frameWidth: number = 165 cpuAbilityEndPointX - cpuAbilityStartPointX <= 1 ? 1 : cpuAbilityEndPointX - cpuAbilityStartPointX; 166 if (!cpuAbilityNode.frame) { 167 cpuAbilityNode.frame = new Rect(0, 0, 0, 0); 168 } 169 cpuAbilityNode.frame.x = Math.floor(cpuAbilityStartPointX); 170 cpuAbilityNode.frame.y = frame.y + padding; 171 cpuAbilityNode.frame.width = Math.ceil(frameWidth); 172 cpuAbilityNode.frame.height = Math.floor(frame.height - padding * 2); 173 } 174} 175