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 {cpu, CpuStruct, WakeupBean} from "./ProcedureWorkerCPU.js"; 17import {drawLines, ns2s, ns2x, Rect} from "./ProcedureWorkerCommon.js"; 18import {CpuFreqStruct, freq} from "./ProcedureWorkerFreq.js"; 19import {proc, ProcessStruct} from "./ProcedureWorkerProcess.js"; 20import {mem, ProcessMemStruct} from "./ProcedureWorkerMem.js"; 21import {thread, ThreadStruct} from "./ProcedureWorkerThread.js"; 22import {func, FuncStruct} from "./ProcedureWorkerFunc.js"; 23import {fps, FpsStruct} from "./ProcedureWorkerFPS.js"; 24import {heap, HeapStruct} from "./ProcedureWorkerHeap.js"; 25import {timeline} from "./ProcedureWorkerTimeline.js"; 26 27let dataList: any = {} 28let dataFilter: any = {} 29let canvasList: any = {} 30let contextList: any = {} 31 32function drawSelection(context: any, params: any) { 33 if (params.isRangeSelect) { 34 params.rangeSelectObject!.startX = Math.floor(ns2x(params.rangeSelectObject!.startNS!, params.startNS, params.endNS, params.totalNS, params.frame)); 35 params.rangeSelectObject!.endX = Math.floor(ns2x(params.rangeSelectObject!.endNS!, params.startNS, params.endNS, params.totalNS, params.frame)); 36 if (context) { 37 context.globalAlpha = 0.5 38 context.fillStyle = "#666666" 39 context.fillRect(params.rangeSelectObject!.startX!, params.frame.y, params.rangeSelectObject!.endX! - params.rangeSelectObject!.startX!, params.frame.height) 40 context.globalAlpha = 1 41 } 42 } 43} 44 45function drawWakeUp(context: CanvasRenderingContext2D | any, wake: WakeupBean | null, startNS: number, endNS: number, totalNS: number, frame: Rect, selectCpuStruct: CpuStruct | undefined = undefined, currentCpu: number | undefined = undefined) { 46} 47 48self.onmessage = function (e: any) { 49 if ((e.data.type as string).startsWith("clear")) { 50 dataList = {}; 51 dataFilter = {}; 52 canvasList = {}; 53 contextList = {}; 54 return; 55 } 56 let res: any 57 // @ts-ignore 58 if (!dataList[e.data.type]) { 59 dataList[e.data.type] = e.data.params.list; 60 dataFilter[e.data.type] = new Set(); 61 if (e.data.params.offscreen) { 62 canvasList[e.data.type] = e.data.params.offscreen; 63 contextList[e.data.type] = e.data.params.offscreen!.getContext('2d'); 64 contextList[e.data.type].scale(e.data.params.dpr, e.data.params.dpr); 65 } 66 } 67 let canvas = canvasList[e.data.type]; 68 let context = contextList[e.data.type]; 69 let type = e.data.type as string; 70 let params = e.data.params; 71 let isRangeSelect = e.data.params.isRangeSelect; 72 let isHover = e.data.params.isHover; 73 let xs = e.data.params.xs; 74 let frame = e.data.params.frame; 75 let hoverX = e.data.params.hoverX; 76 let hoverY = e.data.params.hoverY; 77 let startNS = e.data.params.startNS; 78 let endNS = e.data.params.endNS; 79 let totalNS = e.data.params.totalNS; 80 let canvasWidth = e.data.params.canvasWidth; 81 let canvasHeight = e.data.params.canvasHeight; 82 let useCache = e.data.params.useCache; 83 let lineColor = e.data.params.lineColor; 84 let wakeupBean: WakeupBean | null = e.data.params.wakeupBean; 85 if (canvas) { 86 if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { 87 canvas.width = canvasWidth; 88 canvas.height = canvasHeight; 89 context.scale(e.data.params.dpr, e.data.params.dpr); 90 } 91 } 92 if (type.startsWith("timeline")) { 93 timeline(canvas, context, startNS, endNS, totalNS, frame, 94 e.data.params.keyPressCode, e.data.params.keyUpCode, 95 e.data.params.mouseDown, e.data.params.mouseUp, 96 e.data.params.mouseMove, e.data.params.mouseOut, 97 e.data.params.offsetLeft, e.data.params.offsetTop, 98 (a: any) => { 99 //@ts-ignore 100 self.postMessage({ 101 id: "timeline", 102 type: "timeline-range-changed", 103 results: a, 104 }); 105 } 106 ); 107 // @ts-ignore 108 self.postMessage({ 109 id: e.data.id, 110 type: type, 111 results: null, 112 }); 113 } else if (type.startsWith("cpu")) { 114 if (!useCache) { 115 cpu(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame); 116 } 117 if (canvas) { 118 context.clearRect(0, 0, canvas.width, canvas.height); 119 context.beginPath(); 120 drawLines(context, xs, frame.height, lineColor); 121 CpuStruct.hoverCpuStruct = undefined; 122 if (isHover) { 123 for (let re of dataFilter[e.data.type]) { 124 if (hoverX >= re.frame.x && hoverX <= re.frame.x + re.frame.width && hoverY >= re.frame.y && hoverY <= re.frame.y + re.frame.height) { 125 CpuStruct.hoverCpuStruct = re; 126 break; 127 } 128 } 129 } else { 130 CpuStruct.hoverCpuStruct = e.data.params.hoverCpuStruct; 131 } 132 CpuStruct.selectCpuStruct = e.data.params.selectCpuStruct; 133 for (let re of dataFilter[type]) { 134 CpuStruct.draw(context, re); 135 } 136 drawSelection(context, params); 137 context.closePath(); 138 let currentCpu = parseInt(type.replace("cpu", "")); 139 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame, type == `cpu${CpuStruct.selectCpuStruct?.cpu || 0}` ? CpuStruct.selectCpuStruct : undefined, currentCpu); 140 } 141 // @ts-ignore 142 self.postMessage({ 143 id: e.data.id, 144 type: type, 145 results: canvas ? undefined : dataFilter[type], 146 hover: CpuStruct.hoverCpuStruct 147 }); 148 } else if (type.startsWith("fps")) { 149 if (!useCache) { 150 fps(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame); 151 } 152 if (canvas) { 153 context.clearRect(0, 0, canvas.width, canvas.height); 154 context.beginPath(); 155 drawLines(context, xs, frame.height, lineColor) 156 for (let re of dataFilter[type]) { 157 FpsStruct.draw(context, re) 158 } 159 drawSelection(context, params); 160 context.closePath(); 161 let maxFps = FpsStruct.maxFps + "FPS" 162 let textMetrics = context.measureText(maxFps); 163 context.globalAlpha = 0.8 164 context.fillStyle = "#f0f0f0" 165 context.fillRect(0, 5, textMetrics.width + 8, 18) 166 context.globalAlpha = 1 167 context.fillStyle = "#333" 168 context.textBaseline = "middle" 169 context.fillText(maxFps, 4, 5 + 9); 170 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 171 } 172 // @ts-ignore 173 self.postMessage({id: e.data.id, type: type, results: canvas ? undefined : dataFilter[type], hover: undefined}); 174 } else if (type.startsWith("freq")) { 175 if (!useCache) { 176 freq(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame) 177 } 178 if (canvas) { 179 context.clearRect(0, 0, canvas.width, canvas.height); 180 context.beginPath(); 181 CpuFreqStruct.maxFreq = e.data.params.maxFreq; 182 CpuFreqStruct.maxFreqName = e.data.params.maxFreqName; 183 drawLines(context, xs, frame.height, lineColor) 184 CpuFreqStruct.hoverCpuFreqStruct = undefined; 185 if (isHover) { 186 for (let re of dataFilter[type]) { 187 if (hoverX >= re.frame.x && hoverX <= re.frame.x + re.frame.width && hoverY >= re.frame.y && hoverY <= re.frame.y + re.frame.height) { 188 CpuFreqStruct.hoverCpuFreqStruct = re; 189 break; 190 } 191 } 192 } else { 193 CpuFreqStruct.hoverCpuFreqStruct = e.data.params.hoverCpuFreqStruct; 194 } 195 CpuFreqStruct.selectCpuFreqStruct = e.data.params.selectCpuFreqStruct; 196 for (let re of dataFilter[type]) { 197 CpuFreqStruct.draw(context, re) 198 } 199 drawSelection(context, params); 200 context.closePath(); 201 let s = CpuFreqStruct.maxFreqName 202 let textMetrics = context.measureText(s); 203 context.globalAlpha = 0.8 204 context.fillStyle = "#f0f0f0" 205 context.fillRect(0, 5, textMetrics.width + 8, 18) 206 context.globalAlpha = 1 207 context.fillStyle = "#333" 208 context.textBaseline = "middle" 209 context.fillText(s, 4, 5 + 9) 210 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 211 } 212 // @ts-ignore 213 self.postMessage({ 214 id: e.data.id, 215 type: type, 216 results: canvas ? undefined : dataFilter[type], 217 hover: CpuFreqStruct.hoverCpuFreqStruct 218 }); 219 } else if (type.startsWith("process")) { 220 if (!useCache) { 221 proc(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame) 222 } 223 if (canvas) { 224 context.clearRect(0, 0, canvas.width, canvas.height); 225 context.beginPath(); 226 CpuStruct.cpuCount = e.data.params.cpuCount; 227 drawLines(context, xs, frame.height, lineColor) 228 for (let re of dataFilter[type]) { 229 ProcessStruct.draw(context, re) 230 } 231 drawSelection(context, params); 232 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 233 context.closePath(); 234 } 235 // @ts-ignore 236 self.postMessage({id: e.data.id, type: type, results: canvas ? undefined : dataFilter[type], hover: undefined}); 237 } else if (type.startsWith("heap")) { 238 if (!useCache) { 239 heap(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame); 240 } 241 if (canvas) { 242 context.clearRect(0, 0, canvas.width, canvas.height); 243 context.beginPath(); 244 drawLines(context, xs, frame.height, lineColor) 245 HeapStruct.hoverHeapStruct = undefined; 246 if (isHover) { 247 for (let re of dataFilter[e.data.type]) { 248 if (hoverX >= re.frame.x && hoverX <= re.frame.x + re.frame.width && hoverY >= re.frame.y && hoverY <= re.frame.y + re.frame.height) { 249 HeapStruct.hoverHeapStruct = re; 250 break; 251 } 252 } 253 } else { 254 HeapStruct.hoverHeapStruct = e.data.params.hoverHeapStruct; 255 } 256 for (let re of dataFilter[type]) { 257 HeapStruct.draw(context, re) 258 } 259 drawSelection(context, params); 260 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 261 context.closePath(); 262 } 263 // @ts-ignore 264 self.postMessage({ 265 id: e.data.id, 266 type: type, 267 results: canvas ? undefined : dataFilter[type], 268 hover: HeapStruct.hoverHeapStruct 269 }); 270 } else if (type.startsWith("mem")) { 271 if (!useCache) { 272 mem(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame) 273 } 274 if (canvas) { 275 context.clearRect(0, 0, canvas.width, canvas.height); 276 context.beginPath(); 277 drawLines(context, xs, frame.height, lineColor) 278 for (let re of dataFilter[type]) { 279 ProcessMemStruct.draw(context, re) 280 } 281 drawSelection(context, params); 282 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 283 context.closePath(); 284 } 285 // @ts-ignore 286 self.postMessage({id: e.data.id, type: type, results: canvas ? undefined : dataFilter[type], hover: undefined}); 287 } else if (type.startsWith("thread")) { 288 if (!useCache) { 289 thread(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame) 290 } 291 if (canvas) { 292 context.clearRect(0, 0, canvas.width, canvas.height); 293 context.beginPath(); 294 drawLines(context, xs, frame.height, lineColor) 295 ThreadStruct.hoverThreadStruct = undefined; 296 if (isHover) { 297 for (let re of dataFilter[e.data.type]) { 298 if (hoverX >= re.frame.x && hoverX <= re.frame.x + re.frame.width && hoverY >= re.frame.y && hoverY <= re.frame.y + re.frame.height) { 299 ThreadStruct.hoverThreadStruct = re; 300 break; 301 } 302 } 303 } else { 304 ThreadStruct.hoverThreadStruct = e.data.params.hoverThreadStruct; 305 } 306 ThreadStruct.selectThreadStruct = e.data.params.selectThreadStruct; 307 for (let re of dataFilter[type]) { 308 ThreadStruct.draw(context, re) 309 } 310 drawSelection(context, params); 311 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 312 context.closePath(); 313 } 314 // @ts-ignore 315 self.postMessage({ 316 id: e.data.id, 317 type: type, 318 results: canvas ? undefined : dataFilter[type], 319 hover: ThreadStruct.hoverThreadStruct 320 }); 321 } else if (type.startsWith("func")) { 322 if (!useCache) { 323 func(dataList[type], dataFilter[type], startNS, endNS, totalNS, frame) 324 } 325 if (canvas) { 326 if (canvas.height == 150) { 327 canvas.width = frame.width; 328 canvas.height = e.data.params.maxHeight; 329 context.scale(e.data.params.dpr, e.data.params.dpr); 330 } 331 context.clearRect(0, 0, canvas.width, canvas.height); 332 context.beginPath(); 333 drawLines(context, xs, frame.height, lineColor) 334 FuncStruct.hoverFuncStruct = undefined; 335 if (isHover) { 336 for (let re of dataFilter[e.data.type]) { 337 if (hoverX >= re.frame.x && hoverX <= re.frame.x + re.frame.width && hoverY >= re.frame.y && hoverY <= re.frame.y + re.frame.height) { 338 FuncStruct.hoverFuncStruct = re; 339 break; 340 } 341 } 342 } else { 343 FuncStruct.hoverFuncStruct = e.data.params.hoverFuncStruct; 344 } 345 FuncStruct.selectFuncStruct = e.data.params.selectFuncStruct; 346 for (let re of dataFilter[type]) { 347 FuncStruct.draw(context, re) 348 } 349 drawSelection(context, params); 350 drawWakeUp(context, wakeupBean, startNS, endNS, totalNS, frame); 351 context.closePath(); 352 } 353 // @ts-ignore 354 self.postMessage({ 355 id: e.data.id, 356 type: type, 357 results: canvas ? undefined : dataFilter[type], 358 hover: FuncStruct.hoverFuncStruct 359 }); 360 } 361}; 362self.onmessageerror = function (e: any) { 363} 364 365 366 367 368