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.js"; 17import {BaseStruct} from "./BaseStruct.js"; 18import {WakeupBean} from "./WakeupBean.js"; 19 20export class CpuStruct extends BaseStruct { 21 static cpuCount: number //最大cpu数量 22 static hoverCpuStruct: CpuStruct | undefined; 23 static selectCpuStruct: CpuStruct | undefined; 24 static wakeupBean: WakeupBean | null | undefined = null; 25 cpu: number | undefined 26 dur: number | undefined 27 end_state: string | undefined 28 id: number | undefined 29 name: string | undefined 30 priority: number | undefined 31 processCmdLine: string | undefined 32 processId: number | undefined 33 processName: string | undefined 34 schedId: number | undefined 35 startTime: number | undefined 36 tid: number | undefined 37 type: string | undefined 38 39 static draw(ctx: CanvasRenderingContext2D, data: CpuStruct) { 40 if (data.frame) { 41 let width = data.frame.width || 0; 42 if (data.processId === CpuStruct.hoverCpuStruct?.processId || !CpuStruct.hoverCpuStruct) { 43 ctx.fillStyle = ColorUtils.colorForTid((data.processId || 0) > 0 ? (data.processId || 0) : (data.tid || 0)) 44 } else { 45 ctx.fillStyle = "#e0e0e0" 46 } 47 ctx.fillRect(data.frame.x, data.frame.y, width, data.frame.height) 48 if (width > textPadding * 2) { 49 let process = `${(data.processName || "Process")} [${data.processId}]` 50 let thread = `${data.name || "Thread"} [${data.tid}]` 51 let processMeasure = ctx.measureText(process); 52 let threadMeasure = ctx.measureText(thread); 53 let processCharWidth = Math.round(processMeasure.width / process.length) 54 let threadCharWidth = Math.round(threadMeasure.width / thread.length) 55 ctx.fillStyle = "#ffffff" 56 let y = data.frame.height / 2 + data.frame.y; 57 if (processMeasure.width < width - textPadding * 2) { 58 let x1 = Math.floor(width / 2 - processMeasure.width / 2 + data.frame.x + textPadding) 59 ctx.textBaseline = "bottom"; 60 ctx.fillText(process, x1, y, width - textPadding * 2) 61 } else if (width - textPadding * 2 > processCharWidth * 4) { 62 let chatNum = (width - textPadding * 2) / processCharWidth; 63 let x1 = data.frame.x + textPadding 64 ctx.textBaseline = "bottom"; 65 ctx.fillText(process.substring(0, chatNum - 4) + '...', x1, y, width - textPadding * 2) 66 } 67 if (threadMeasure.width < width - textPadding * 2) { 68 ctx.textBaseline = "top"; 69 let x2 = Math.floor(width / 2 - threadMeasure.width / 2 + data.frame.x + textPadding) 70 ctx.fillText(thread, x2, y + 2, width - textPadding * 2) 71 } else if (width - textPadding * 2 > threadCharWidth * 4) { 72 let chatNum = (width - textPadding * 2) / threadCharWidth; 73 let x1 = data.frame.x + textPadding 74 ctx.textBaseline = "top"; 75 ctx.fillText(thread.substring(0, chatNum - 4) + '...', x1, y + 2, width - textPadding * 2) 76 } 77 } 78 if (CpuStruct.selectCpuStruct && CpuStruct.equals(CpuStruct.selectCpuStruct, data)) { 79 ctx.strokeStyle = '#232c5d' 80 ctx.lineWidth = 2 81 ctx.strokeRect(data.frame.x, data.frame.y, width - 2, data.frame.height) 82 } 83 } 84 } 85 86 static equals(d1: CpuStruct, d2: CpuStruct): boolean { 87 if (d1 && d2 && d1.cpu == d2.cpu && 88 d1.tid == d2.tid && 89 d1.processId == d2.processId && 90 d1.startTime == d2.startTime && 91 d1.dur == d2.dur) { 92 return true; 93 } else { 94 return false; 95 } 96 } 97} 98 99const textPadding = 2; 100 101