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 drawFlagLine, 20 drawLines, 21 drawLoading, 22 drawLoadingFrame, 23 drawSelection, 24 drawWakeUp, 25 ns2x, 26 Render, 27 RequestMessage, 28} from './ProcedureWorkerCommon'; 29import { CpuStruct } from './cpu/ProcedureWorkerCPU'; 30import { TraceRow } from '../../component/trace/base/TraceRow'; 31 32export class ProcessRender extends Render { 33 renderMainThread(req: any, row: TraceRow<ProcessStruct>) { 34 let list = row.dataList; 35 let filter = row.dataListCache; 36 proc( 37 list, 38 filter, 39 TraceRow.range!.startNS || 0, 40 TraceRow.range!.endNS || 0, 41 TraceRow.range!.totalNS || 0, 42 row.frame, 43 req.useCache || !TraceRow.range!.refresh 44 ); 45 drawLoadingFrame(req.context, filter, row, true); 46 req.context.beginPath(); 47 let path = new Path2D(); 48 let miniHeight: number = 0; 49 miniHeight = Math.round((row.frame.height - CpuStruct.cpuCount * 2) / CpuStruct.cpuCount); 50 req.context.fillStyle = ColorUtils.colorForTid(req.pid || 0); 51 for (let re of filter) { 52 ProcessStruct.draw(req.context, path, re, miniHeight); 53 } 54 req.context.fill(path); 55 req.context.closePath(); 56 } 57} 58export function proc( 59 processList: Array<any>, 60 res: Array<any>, 61 startNS: number, 62 endNS: number, 63 totalNS: number, 64 frame: any, 65 use: boolean 66) { 67 if (use && res.length > 0) { 68 res.forEach((it) => ProcessStruct.setProcessFrame(it, 5, startNS, endNS, totalNS, frame)); 69 return; 70 } 71 res.length = 0; 72 if (processList) { 73 for (let i = 0, len = processList.length; i < len; i++) { 74 let it = processList[i]; 75 if ((it.startTime || 0) + (it.dur || 0) > startNS && (it.startTime || 0) < endNS) { 76 ProcessStruct.setProcessFrame(processList[i], 5, startNS, endNS, totalNS, frame); 77 if ( 78 !( 79 i > 0 && 80 (processList[i - 1].frame.x || 0) == (processList[i].frame.x || 0) && 81 (processList[i - 1].frame.width || 0) == (processList[i].frame.width || 0) 82 ) 83 ) { 84 res.push(processList[i]); 85 } 86 } 87 } 88 } 89} 90 91const padding = 1; 92 93export class ProcessStruct extends BaseStruct { 94 cpu: number | undefined; 95 dur: number | undefined; 96 id: number | undefined; 97 pid: number | undefined; 98 process: string | undefined; 99 startTime: number | undefined; 100 state: string | undefined; 101 thread: string | undefined; 102 tid: number | undefined; 103 ts: number | undefined; 104 type: string | undefined; 105 utid: number | undefined; 106 107 static draw(ctx: CanvasRenderingContext2D, path: Path2D, data: ProcessStruct, miniHeight: number) { 108 if (data.frame) { 109 path.rect(data.frame.x, data.frame.y + (data.cpu || 0) * miniHeight + padding, data.frame.width, miniHeight); 110 } 111 } 112 113 static setFrame(processNode: any, pns: number, startNS: number, endNS: number, frame: any) { 114 if ((processNode.startTime || 0) < startNS) { 115 processNode.frame.x = 0; 116 } else { 117 processNode.frame.x = Math.floor(((processNode.startTime || 0) - startNS) / pns); 118 } 119 if ((processNode.startTime || 0) + (processNode.dur || 0) > endNS) { 120 processNode.frame.width = frame.width - processNode.frame.x; 121 } else { 122 processNode.frame.width = Math.ceil( 123 ((processNode.startTime || 0) + (processNode.dur || 0) - startNS) / pns - processNode.frame.x 124 ); 125 } 126 if (processNode.frame.width < 1) { 127 processNode.frame.width = 1; 128 } 129 } 130 131 static setProcessFrame( 132 processNode: any, 133 padding: number, 134 startNS: number, 135 endNS: number, 136 totalNS: number, 137 frame: any 138 ) { 139 let x1: number; 140 let x2: number; 141 if ((processNode.startTime || 0) < startNS) { 142 x1 = 0; 143 } else { 144 x1 = ns2x(processNode.startTime || 0, startNS, endNS, totalNS, frame); 145 } 146 if ((processNode.startTime || 0) + (processNode.dur || 0) > endNS) { 147 x2 = frame.width; 148 } else { 149 x2 = ns2x((processNode.startTime || 0) + (processNode.dur || 0), startNS, endNS, totalNS, frame); 150 } 151 let processGetV: number = x2 - x1 <= 1 ? 1 : x2 - x1; 152 if (!processNode.frame) { 153 processNode.frame = {}; 154 } 155 processNode.frame.x = Math.floor(x1); 156 processNode.frame.y = Math.floor(frame.y + 2); 157 processNode.frame.width = Math.ceil(processGetV); 158 processNode.frame.height = Math.floor(frame.height - padding * 2); 159 } 160} 161