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 { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; 17import { LitTable } from '../../../../../base-ui/table/lit-table.js'; 18import { GpuMemory } from '../../../../bean/AbilityMonitor.js'; 19import { MemoryConfig } from '../../../../bean/MemoryConfig.js'; 20import { getTabGpuMemoryVMTrackerClickData } from '../../../../database/SqlLite.js'; 21import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon.js'; 22import { Utils } from '../../base/Utils.js'; 23 24@element('tabpane-gpu-memory-selection-vmtracker') 25export class TabPaneGpuMemorySelectVmTracker extends BaseElement { 26 private gpuMemoryClickTable: LitTable | null | undefined; 27 private gpuMemoryClickSource: Array<GpuMemory> = []; 28 private tableThead: HTMLDivElement | undefined | null; 29 30 initElements(): void { 31 this.gpuMemoryClickTable = this.shadowRoot?.querySelector<LitTable>('#gpuMemoryClickTable'); 32 this.tableThead = this.gpuMemoryClickTable?.shadowRoot?.querySelector('.thead') as HTMLDivElement; 33 this.gpuMemoryClickTable!.addEventListener('column-click', (e) => { 34 // @ts-ignore 35 this.sortGpuMemoryByColumn(e.detail.key, e.detail.sort); 36 }); 37 } 38 39 connectedCallback(): void { 40 super.connectedCallback(); 41 new ResizeObserver(() => { 42 if (this.parentElement?.clientHeight != 0) { 43 // @ts-ignore 44 this.gpuMemoryClickTable?.shadowRoot?.querySelector('.table').style.height = this.parentElement.clientHeight - 18 + 'px'; 45 this.parentElement!.style.overflow = 'hidden'; 46 this.gpuMemoryClickTable?.reMeauseHeight(); 47 } 48 }).observe(this.parentElement!); 49 } 50 51 private init(): void { 52 const thTable = this.tableThead!.querySelector('.th'); 53 const gpuMemoryVmTrackerTblNodes = thTable!.querySelectorAll('div'); 54 if (this.tableThead!.hasAttribute('sort')) { 55 this.tableThead!.removeAttribute('sort'); 56 gpuMemoryVmTrackerTblNodes.forEach((item) => { 57 item.querySelectorAll('svg').forEach((svg) => { 58 svg.style.display = 'none'; 59 }); 60 }); 61 } 62 } 63 64 queryGpuMemoryVmTrackerClickDataByDB(startNs: number): void { 65 this.init(); 66 getTabGpuMemoryVMTrackerClickData(startNs, MemoryConfig.getInstance().iPid).then((data) => { 67 if (data.length !== null && data.length > 0) { 68 data.forEach((item) => { 69 if (item.threadName !== null) { 70 item.thread = `${item.threadName}(${item.threadId})`; 71 } else { 72 item.thread = `Thread(${item.threadId})`; 73 } 74 item.timeStamp = ns2s(item.startNs); 75 item.sizes = Utils.getBinaryByteWithUnit(item.size); 76 }); 77 this.gpuMemoryClickTable!.recycleDataSource = data.sort(function ( 78 gpuMemoryLeftData: GpuMemory, 79 gpuMemoryRightData: GpuMemory 80 ) { 81 return gpuMemoryRightData.size - gpuMemoryLeftData.size; 82 }); 83 this.gpuMemoryClickSource = data; 84 } else { 85 this.gpuMemoryClickTable!.recycleDataSource = []; 86 this.gpuMemoryClickSource = []; 87 } 88 }); 89 } 90 91 initHtml(): string { 92 return ` 93<style> 94.gpuMemoryClickTable{ 95 height: auto; 96} 97:host{ 98 display: flex; 99 flex-direction: column; 100 padding: 10px 10px; 101} 102</style> 103<lit-table id="gpuMemoryClickTable" class="gpuMemoryClickTable"> 104 <lit-table-column order title="TimeStamp" data-index="timeStamp" key="startNs" align="flex-start" width="1fr" > 105 </lit-table-column> 106 <lit-table-column order title="GpuName" data-index="gpuName" key="gpuName" align="flex-start" width="1fr" > 107 </lit-table-column> 108 <lit-table-column order title="Thread(tid)" data-index="thread" key="thread" align="flex-start" width="1fr" > 109 </lit-table-column> 110 <lit-table-column order title="Size" data-index="sizes" key="size" align="flex-start" width="1fr" > 111 </lit-table-column> 112</lit-table> 113 `; 114 } 115 116 sortGpuMemoryByColumn(column: string, sort: number): void { 117 switch (sort) { 118 case 0: 119 this.gpuMemoryClickTable!.recycleDataSource = this.gpuMemoryClickSource; 120 break; 121 default: 122 let array = [...this.gpuMemoryClickSource]; 123 switch (column) { 124 case 'startNs': 125 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 126 return sort === 1 127 ? gpuMemoryLeftData.startNs - gpuMemoryRightData.startNs 128 : gpuMemoryRightData.startNs - gpuMemoryLeftData.startNs; 129 }); 130 break; 131 case 'gpuName': 132 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 133 return sort === 1 134 ? `${gpuMemoryLeftData.gpuName}`.localeCompare(`${gpuMemoryRightData.gpuName}`) 135 : `${gpuMemoryRightData.gpuName}`.localeCompare(`${gpuMemoryLeftData.gpuName}`); 136 }); 137 break; 138 case 'size': 139 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 140 return sort === 1 141 ? gpuMemoryLeftData.size - gpuMemoryRightData.size 142 : gpuMemoryRightData.size - gpuMemoryLeftData.size; 143 }); 144 break; 145 case 'thread': 146 this.gpuMemoryClickTable!.recycleDataSource = array.sort((gpuMemoryLeftData, gpuMemoryRightData) => { 147 return sort === 1 148 ? `${gpuMemoryLeftData.thread}`.localeCompare(`${gpuMemoryRightData.thread}`) 149 : `${gpuMemoryRightData.thread}`.localeCompare(`${gpuMemoryLeftData.thread}`); 150 }); 151 break; 152 } 153 break; 154 } 155 } 156} 157