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