• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
15import { BaseElement, element } from '../../../../../base-ui/BaseElement.js';
16import { LitSelect } from '../../../../../base-ui/select/LitSelect.js';
17import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption.js';
18import { LitTable } from '../../../../../base-ui/table/lit-table.js';
19import { queryGpuDataByTs } from '../../../../database/SqlLite.js';
20import { SnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerSnapshot.js';
21import { VmTrackerChart } from '../../../chart/SpVmTrackerChart.js';
22import { SpSystemTrace } from '../../../SpSystemTrace.js';
23import { Utils } from '../../base/Utils.js';
24import { compare, CompareStruct, resizeObserverFromMemory } from '../SheetUtils.js';
25import '../TabPaneJsMemoryFilter.js';
26import { TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter.js';
27import { TabPaneGpuClickSelect } from './TabPaneGpuClickSelect.js';
28interface GpuTreeItem {
29  name: string;
30  id: number;
31  size: number;
32  sizeStr: string;
33  children?: GpuTreeItem[] | undefined;
34}
35@element('tabpane-gpu-click-select-comparison')
36export class TabPaneGpuClickSelectComparison extends TabPaneGpuClickSelect {
37  private comparisonSelect: TabPaneJsMemoryFilter | null | undefined;
38  private selectEl: LitSelect | null | undefined;
39  private gpuComparisonTbl: LitTable | null | undefined;
40  private baseGpuData: Array<GpuDumpComparison> = [];
41  private gpuComparisonSource: Array<GpuTreeItem> = [];
42  private comparisonSortData: Array<GpuTreeItem> = [];
43
44  initElements(): void {
45    this.gpuComparisonTbl = this.shadowRoot?.querySelector<LitTable>('#tb-gpu');
46    this.comparisonSelect = this.shadowRoot?.querySelector('#filter') as TabPaneJsMemoryFilter;
47    this.selectEl = this.comparisonSelect?.shadowRoot?.querySelector<LitSelect>('lit-select');
48    this.gpuComparisonTbl!.addEventListener('column-click', (e) => {
49      // @ts-ignore
50      this.sortGpuByColumn(e.detail.key, e.detail.sort);
51    });
52  }
53  connectedCallback(): void {
54    super.connectedCallback();
55    resizeObserverFromMemory(this.parentElement!, this.gpuComparisonTbl!, this.comparisonSelect!);
56  }
57  async queryDataByDB(type: string, startTs: number): Promise<any> {
58    let gpuData: Array<any> = [];
59    let window = type === 'total' ? 0 : VmTrackerChart.gpuWindow;
60    let module = type === 'total' ? VmTrackerChart.gpuTotalModule : VmTrackerChart.gpuWindowModule;
61    await queryGpuDataByTs(startTs, window || 0, module).then((result) => {
62      gpuData = result;
63    });
64    return gpuData;
65  }
66  async getGpuClickDataByDB(type: string, startTs: number, dataList: Array<SnapshotStruct>) {
67    const dataArray = [];
68    let label = this.gpuComparisonTbl!.shadowRoot!.querySelector('.thead')?.firstChild?.firstChild?.firstChild;
69    if (label) {
70      (label as HTMLLabelElement).innerHTML = type === 'total' ? 'Module / Category' : 'Window / Module / Category';
71    }
72    //@ts-ignore
73    this.gpuComparisonTbl?.shadowRoot?.querySelector('.table')?.style?.height =
74      this.parentElement!.clientHeight - 45 + 'px';
75    this.gpuComparisonTbl!.loading = true;
76    this.baseGpuData = [];
77    let baseGpuData = await this.queryDataByDB(type, startTs);
78    for (const item of baseGpuData) {
79      this.baseGpuData.push(
80        new GpuDumpComparison(item.windowNameId, item.windowId, item.moduleId, item.categoryId, item.size)
81      );
82    }
83    for (let item of dataList) {
84      if (item.startNs !== startTs) {
85        dataArray.push(item);
86      }
87    }
88    this.selectStamps(dataArray, type);
89    this.getComparisonData(dataArray[0].startNs, type);
90  }
91  selectStamps(gpuSelectComList: Array<SnapshotStruct>, type: string): void {
92    let input = this.selectEl!.shadowRoot?.querySelector('input') as HTMLInputElement;
93    this.selectEl!.innerHTML = '';
94    let option = new LitSelectOption();
95    option.innerHTML = 'File Name';
96    option.setAttribute('disabled', 'disabled');
97    this.selectEl?.appendChild(option);
98    if (gpuSelectComList[0].name) {
99      option.setAttribute('value', gpuSelectComList[0].name);
100    }
101    option.setAttribute('value', gpuSelectComList[0].name);
102    this.selectEl!.defaultValue = gpuSelectComList[0].name || '';
103    this.selectEl!.placeholder = gpuSelectComList[0].name || '';
104    this.selectEl!.dataSource = gpuSelectComList;
105    this.selectEl!.querySelectorAll('lit-select-option').forEach((option) => {
106      option.addEventListener('onSelected', async (e) => {
107        for (let f of gpuSelectComList) {
108          if (input.value === f.name) {
109            this.getComparisonData(f.startNs, type);
110          }
111        }
112        e.stopPropagation();
113      });
114    });
115  }
116  async getComparisonData(targetStartNs: number, type: string) {
117    let comparisonData: Array<GpuDumpComparison> = [];
118    let targetGpuData: Array<GpuDumpComparison> = [];
119    let data = await this.queryDataByDB(type, targetStartNs);
120    for (const item of data) {
121      targetGpuData.push(
122        new GpuDumpComparison(item.windowNameId, item.windowId, item.moduleId, item.categoryId, item.size)
123      );
124    }
125    comparisonData = compare(this.baseGpuData!, targetGpuData);
126    for (const item of comparisonData) {
127      item.size = item.value;
128    }
129    let items = this.createTreeData(comparisonData);
130    this.gpuComparisonSource = (type === 'total' ? items[0].children : items) || [];
131    this.comparisonSortData = this.gpuComparisonSource;
132    this.gpuComparisonTbl!.recycleDataSource = this.gpuComparisonSource;
133    this.gpuComparisonTbl!.loading = false;
134  }
135
136  sortGpuByColumn(column: string, sort: number): void {
137    switch (sort) {
138      case 0:
139        this.gpuComparisonTbl!.recycleDataSource = this.comparisonSortData;
140        break;
141      default:
142        let array = [...this.comparisonSortData];
143        switch (column) {
144          case 'name':
145            this.gpuComparisonTbl!.recycleDataSource = array.sort((gpuComparisonLeftData, gpuComparisonRightData) => {
146              return sort === 1
147                ? `${gpuComparisonLeftData.name}`.localeCompare(`${gpuComparisonRightData.name}`)
148                : `${gpuComparisonRightData.name}`.localeCompare(`${gpuComparisonLeftData.name}`);
149            });
150            break;
151          case 'sizeDelta':
152            this.gpuComparisonTbl!.recycleDataSource = array.sort((gpuComparisonLeftData, gpuComparisonRightData) => {
153              return sort === 1
154                ? gpuComparisonLeftData.size - gpuComparisonRightData.size
155                : gpuComparisonRightData.size - gpuComparisonLeftData.size;
156            });
157            break;
158        }
159        break;
160    }
161  }
162
163  initHtml(): string {
164    return `
165    <style>
166    :host{
167        display: flex;
168        flex-direction: column;
169        padding: 10px 10px;
170    }
171    </style>
172    <lit-table id="tb-gpu" style="height: auto" tree>
173            <lit-table-column width="50%" title="Window / Module / Category" data-index="name" key="name" align="flex-start" order>
174            </lit-table-column>
175            <lit-table-column width="1fr" title="SizeDelta" data-index="sizeStr" key="sizeDelta"  align="flex-start" order >
176            </lit-table-column>
177    </lit-table>
178    <tab-pane-js-memory-filter id="filter" first hideFilter ></tab-pane-js-memory-filter>
179        `;
180  }
181}
182export class GpuDumpComparison extends CompareStruct {
183  windowNameId: number = -1;
184  windowId: number = -1;
185  moduleId: number = -1;
186  categoryId: number = -1;
187  size: number = -1;
188  constructor(windowNameId: number, windowId: number, moduleId: number, categoryId: number, value: number) {
189    super(`${windowNameId}` + '' + `${windowId}` + '' + `${moduleId}` + '' + `${categoryId}`, value);
190    this.windowNameId = windowNameId;
191    this.moduleId = moduleId;
192    this.windowId = windowId;
193    this.categoryId = categoryId;
194  }
195  clone(isBase?: boolean): GpuDumpComparison {
196    const value = isBase ? this.value : -this.value;
197    return new GpuDumpComparison(this.windowNameId, this.windowId, this.moduleId, this.categoryId, value);
198  }
199}
200