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 { SpSystemTrace } from '../SpSystemTrace'; 17import { TraceRow } from '../trace/base/TraceRow'; 18import { VirtualMemoryRender, VirtualMemoryStruct } from '../../database/ui-worker/ProcedureWorkerVirtualMemory'; 19import { renders } from '../../database/ui-worker/ProcedureWorker'; 20import { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU'; 21import { virtualMemoryDataSender } from '../../database/data-trafic/VirtualMemoryDataSender'; 22import { queryVirtualMemory } from '../../database/sql/Memory.sql'; 23import { NUM_16 } from '../../bean/NumBean'; 24import { BaseStruct } from '../../bean/BaseStruct'; 25 26export class SpVirtualMemChart { 27 trace: SpSystemTrace; 28 29 constructor(trace: SpSystemTrace) { 30 this.trace = trace; 31 } 32 33 async init(): Promise<void> { 34 let array = await queryVirtualMemory(); 35 if (array.length === 0) { 36 return; 37 } 38 let vmFolder = TraceRow.skeleton(); 39 vmFolder.rowId = 'VirtualMemory'; 40 vmFolder.index = 0; 41 vmFolder.rowType = TraceRow.ROW_TYPE_VIRTUAL_MEMORY_GROUP; 42 vmFolder.rowParentId = ''; 43 vmFolder.folder = true; 44 vmFolder.name = 'Virtual Memory'; 45 vmFolder.style.height = '40px'; 46 vmFolder.favoriteChangeHandler = this.trace.favoriteChangeHandler; 47 vmFolder.selectChangeHandler = this.trace.selectChangeHandler; 48 vmFolder.supplier = async (): Promise<BaseStruct[]> => new Promise<[]>((resolve) => resolve([])); 49 vmFolder.onThreadHandler = (useCache): void => { 50 vmFolder.canvasSave(this.trace.canvasPanelCtx!); 51 if (vmFolder.expansion) { 52 // @ts-ignore 53 this.trace.canvasPanelCtx?.clearRect(0, 0, vmFolder.frame.width, vmFolder.frame.height); 54 } else { 55 (renders.empty as EmptyRender).renderMainThread( 56 { 57 context: this.trace.canvasPanelCtx, 58 useCache: useCache, 59 type: '', 60 }, 61 vmFolder 62 ); 63 } 64 vmFolder.canvasRestore(this.trace.canvasPanelCtx!, this.trace); 65 }; 66 this.trace.rowsEL?.appendChild(vmFolder); 67 //@ts-ignore 68 array.forEach((it) => this.initVirtualMemoryRow(vmFolder, it.id, it.name)); 69 } 70 71 private initVirtualMemoryChartRow( 72 id: number, 73 folder: TraceRow<BaseStruct>, 74 name: string 75 ): TraceRow<VirtualMemoryStruct> { 76 let virtualMemoryRow = TraceRow.skeleton<VirtualMemoryStruct>(); 77 virtualMemoryRow.rowId = `${id}`; 78 virtualMemoryRow.rowType = TraceRow.ROW_TYPE_VIRTUAL_MEMORY; 79 virtualMemoryRow.rowParentId = folder.rowId; 80 virtualMemoryRow.rowHidden = !folder.expansion; 81 virtualMemoryRow.style.height = '40px'; 82 virtualMemoryRow.name = `${name.substring(NUM_16)}`; 83 virtualMemoryRow.setAttribute('children', ''); 84 virtualMemoryRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 85 virtualMemoryRow.selectChangeHandler = this.trace.selectChangeHandler; 86 virtualMemoryRow.focusHandler = (): void => { 87 this.trace?.displayTip( 88 virtualMemoryRow, 89 VirtualMemoryStruct.hoverStruct, 90 `<span>value:${VirtualMemoryStruct.hoverStruct?.value}</span>` 91 ); 92 }; 93 virtualMemoryRow.findHoverStruct = (): void => { 94 VirtualMemoryStruct.hoverStruct = virtualMemoryRow.getHoverStruct(); 95 }; 96 return virtualMemoryRow; 97 } 98 99 initVirtualMemoryRow(folder: TraceRow<BaseStruct>, id: number, name: string): void { 100 let virtualMemoryRow = this.initVirtualMemoryChartRow(id, folder, name); 101 virtualMemoryRow.supplierFrame = async (): Promise<VirtualMemoryStruct[]> => 102 virtualMemoryDataSender(id, virtualMemoryRow).then((resultVm) => { 103 let maxValue = 0; 104 if (!virtualMemoryRow.isComplete) { 105 maxValue = Math.max(...resultVm.map((it) => it.value || 0)); 106 virtualMemoryRow.setAttribute('maxValue', maxValue.toString() || ''); 107 } 108 for (let j = 0; j < resultVm.length; j++) { 109 if (!virtualMemoryRow.isComplete) { 110 resultVm[j].maxValue = maxValue; 111 } else { 112 resultVm[j].maxValue = Number(virtualMemoryRow.getAttribute('maxValue')); 113 } 114 if (j === resultVm.length - 1) { 115 resultVm[j].duration = (TraceRow.range?.totalNS || 0) - (resultVm[j].startTime || 0); 116 } else { 117 resultVm[j].duration = (resultVm[j + 1].startTime || 0) - (resultVm[j].startTime || 0); 118 } 119 if (j > 0) { 120 resultVm[j].delta = (resultVm[j].value || 0) - (resultVm[j - 1].value || 0); 121 } else { 122 resultVm[j].delta = 0; 123 } 124 } 125 return resultVm; 126 }); 127 virtualMemoryRow.onThreadHandler = (useCache): void => { 128 let context: CanvasRenderingContext2D; 129 if (virtualMemoryRow.currentContext) { 130 context = virtualMemoryRow.currentContext; 131 } else { 132 context = virtualMemoryRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 133 } 134 virtualMemoryRow.canvasSave(context); 135 (renders['virtual-memory-cell'] as VirtualMemoryRender).renderMainThread( 136 { 137 context: context, 138 useCache: useCache, 139 type: `virtual-memory-cell-${id}`, 140 }, 141 virtualMemoryRow 142 ); 143 virtualMemoryRow.canvasRestore(context, this.trace); 144 }; 145 folder.addChildTraceRow(virtualMemoryRow); 146 } 147} 148