• 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 */
15
16import { SpSystemTrace } from '../SpSystemTrace';
17import { info } from '../../../log/Log';
18import { TraceRow } from '../trace/base/TraceRow';
19import { ColorUtils } from '../trace/base/ColorUtils';
20import { CpuFreqLimitRender, CpuFreqLimitsStruct } from '../../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits';
21import { renders } from '../../database/ui-worker/ProcedureWorker';
22import { CpuFreqStruct, FreqRender } from '../../database/ui-worker/ProcedureWorkerFreq';
23import { CpuStateRender, CpuStateStruct } from '../../database/ui-worker/cpu/ProcedureWorkerCpuState';
24import { FolderSupplier, FolderThreadHandler } from './SpChartManager';
25import { Utils } from '../trace/base/Utils';
26import { cpuFreqDataSender } from '../../database/data-trafic/cpu/CpuFreqDataSender';
27import { cpuStateSender } from '../../database/data-trafic/cpu/CpuStateSender';
28import { cpuFreqLimitSender } from '../../database/data-trafic/cpu/CpuFreqLimitDataSender';
29import {
30  getCpuLimitFreqId,
31  getCpuLimitFreqMax,
32  queryCpuFreq,
33  queryCpuMaxFreq,
34  queryCpuStateFilter
35} from "../../database/sql/Cpu.sql";
36export class SpFreqChart {
37  private trace: SpSystemTrace;
38  private folderRow: TraceRow<any> | undefined;
39  private folderRowState: TraceRow<any> | undefined;
40  private folderRowLimit: TraceRow<any> | undefined;
41
42  constructor(trace: SpSystemTrace) {
43    this.trace = trace;
44  }
45
46  async init() {
47    let freqList = await queryCpuFreq();
48    let cpuStateFilterIds = await queryCpuStateFilter();
49    let cpuFreqLimits = await getCpuLimitFreqId();
50    let cpuFreqLimitsMax = await getCpuLimitFreqMax(cpuFreqLimits.map((limit) => limit.maxFilterId).join(','));
51    if (freqList.length > 0) {
52      this.folderRow = TraceRow.skeleton();
53      this.folderRow.rowId = 'Cpu Frequency';
54      this.folderRow.rowParentId = '';
55      this.folderRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ_ALL;
56      this.folderRow.style.height = '40px';
57      this.folderRow.style.width = '100%';
58      this.folderRow.name = 'Cpu Frequency';
59      this.folderRow.folder = true;
60      this.folderRow.rowHidden = this.folderRow!.expansion;
61      this.folderRow.setAttribute('children', '');
62      this.folderRow.supplier = FolderSupplier();
63      this.folderRow.onThreadHandler = FolderThreadHandler(this.folderRow, this.trace);
64      this.trace.rowsEL?.appendChild(this.folderRow);
65
66      info('Cpu Freq data size is: ', freqList!.length);
67      let freqMaxList = await queryCpuMaxFreq();
68      CpuFreqStruct.maxFreq = freqMaxList[0].maxFreq;
69      let maxFreqObj = Utils.getFrequencyWithUnit(freqMaxList[0].maxFreq);
70      CpuFreqStruct.maxFreq = maxFreqObj.maxFreq;
71      CpuFreqStruct.maxFreqName = maxFreqObj.maxFreqName;
72      this.trace.stateRowsId = cpuStateFilterIds;
73      for (let i = 0; i < freqList.length; i++) {
74        const it = freqList[i];
75        let traceRow = TraceRow.skeleton<CpuFreqStruct>();
76        traceRow.rowId = `${it.filterId}`;
77        traceRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ;
78        traceRow.rowParentId = '';
79        traceRow.style.height = '40px';
80        traceRow.name = `Cpu ${it.cpu} Frequency`;
81        traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
82        traceRow.selectChangeHandler = this.trace.selectChangeHandler;
83        traceRow.supplierFrame = () => {
84          return cpuFreqDataSender(it.cpu, traceRow); //queryCpuFreqData
85        };
86        traceRow.focusHandler = (ev) => {
87          this.trace?.displayTip(
88            traceRow,
89            CpuFreqStruct.hoverCpuFreqStruct,
90            `<span>${ColorUtils.formatNumberComma(CpuFreqStruct.hoverCpuFreqStruct?.value!)} kHz</span>`
91          );
92        };
93        traceRow.findHoverStruct = () => {
94          CpuFreqStruct.hoverCpuFreqStruct = traceRow.getHoverStruct(true,false, 'value');
95        };
96        traceRow.onThreadHandler = (useCache) => {
97          let context: CanvasRenderingContext2D;
98          if (traceRow.currentContext) {
99            context = traceRow.currentContext;
100          } else {
101            context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
102          }
103          traceRow.canvasSave(context);
104          (renders['freq'] as FreqRender).renderMainThread(
105            {
106              context: context,
107              useCache: useCache,
108              type: `freq${it.cpu}`,
109            },
110            traceRow
111          );
112          traceRow.canvasRestore(context, this.trace);
113        };
114        this.trace.rowsEL?.appendChild(traceRow);
115        this.folderRow!.addChildTraceRow(traceRow);
116      }
117    }
118    if (cpuStateFilterIds.length > 0) {
119      this.folderRowState = TraceRow.skeleton();
120      this.folderRowState.rowId = 'Cpu State';
121      this.folderRowState.rowType = TraceRow.ROW_TYPE_CPU_STATE_ALL;
122      this.folderRowState.style.height = '40px';
123      this.folderRowState.folder = true;
124      this.folderRowState.style.width = '100%';
125      this.folderRowState.rowParentId = '';
126      this.folderRowState.name = 'Cpu State';
127      this.folderRowState.rowHidden = this.folderRowState!.expansion;
128      this.folderRowState.setAttribute('children', '');
129      this.folderRowState.supplier = FolderSupplier();
130      this.folderRowState.onThreadHandler = FolderThreadHandler(this.folderRowState, this.trace);
131      this.trace.rowsEL?.appendChild(this.folderRowState);
132
133      for (let it of cpuStateFilterIds) {
134        let cpuStateRow = TraceRow.skeleton<CpuStateStruct>();
135        cpuStateRow.rowId = `${it.filterId}`;
136        cpuStateRow.rowType = TraceRow.ROW_TYPE_CPU_STATE;
137        cpuStateRow.rowParentId = '';
138        cpuStateRow.style.height = '40px';
139        cpuStateRow.name = `Cpu ${it.cpu} State`;
140        cpuStateRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
141        cpuStateRow.selectChangeHandler = this.trace.selectChangeHandler;
142        cpuStateRow.isHover = true;
143        cpuStateRow.supplierFrame = () => {
144          return cpuStateSender(it.filterId, cpuStateRow).then((rs) => {
145            rs.forEach((t) => {
146              t.cpu = it.cpu;
147            });
148            return rs;
149          });
150        };
151        cpuStateRow.focusHandler = (ev) => {
152          this.trace.displayTip(
153            cpuStateRow,
154            CpuStateStruct.hoverStateStruct,
155            `<span>State: ${CpuStateStruct.hoverStateStruct?.value}</span>`
156          );
157        };
158        cpuStateRow.findHoverStruct = () => {
159          CpuStateStruct.hoverStateStruct = cpuStateRow.getHoverStruct();
160        };
161        cpuStateRow.onThreadHandler = (useCache: boolean) => {
162          let context: CanvasRenderingContext2D;
163          if (cpuStateRow.currentContext) {
164            context = cpuStateRow.currentContext;
165          } else {
166            context = cpuStateRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
167          }
168          cpuStateRow.canvasSave(context);
169          (renders['cpu-state'] as CpuStateRender).renderMainThread(
170            {
171              cpuStateContext: context,
172              useCache: useCache,
173              type: `cpu-state-${it.cpu}`,
174              cpu: it.cpu,
175            },
176            cpuStateRow
177          );
178          cpuStateRow.canvasRestore(context, this.trace);
179        };
180        this.folderRowState!.addChildTraceRow(cpuStateRow);
181      }
182    }
183    if (cpuFreqLimits.length > 0) {
184      this.folderRowLimit = TraceRow.skeleton();
185      this.folderRowLimit.rowId = 'Cpu Freq Limit';
186      this.folderRowLimit.rowType = TraceRow.ROW_TYPE_CPU_FREQ_LIMITALL;
187      this.folderRowLimit.style.height = '40px';
188      this.folderRowLimit.rowParentId = '';
189      this.folderRowLimit.folder = true;
190      this.folderRowLimit.name = 'Cpu Freq Limit';
191      this.folderRowLimit.rowHidden = this.folderRowLimit!.expansion;
192      this.folderRowLimit.setAttribute('children', '');
193      this.folderRowLimit.supplier = FolderSupplier();
194      this.folderRowLimit.onThreadHandler = FolderThreadHandler(this.folderRowLimit, this.trace);
195      this.trace.rowsEL?.appendChild(this.folderRowLimit);
196
197      for (let limit of cpuFreqLimits) {
198        let findMax = Utils.getFrequencyWithUnit(
199          cpuFreqLimitsMax.find((maxLimit) => {
200            return maxLimit.filterId == limit.maxFilterId;
201          })?.maxValue || 0
202        );
203        let cpuFreqLimitRow = TraceRow.skeleton<CpuFreqLimitsStruct>();
204        cpuFreqLimitRow.rowId = `${limit.cpu}`;
205        cpuFreqLimitRow.rowType = TraceRow.ROW_TYPE_CPU_FREQ_LIMIT;
206        cpuFreqLimitRow.rowParentId = '';
207        cpuFreqLimitRow.style.height = '40px';
208        cpuFreqLimitRow.name = `Cpu ${limit.cpu} Freq Limit`;
209        cpuFreqLimitRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
210        cpuFreqLimitRow.selectChangeHandler = this.trace.selectChangeHandler;
211        cpuFreqLimitRow.setAttribute('maxFilterId', `${limit.maxFilterId}`);
212        cpuFreqLimitRow.setAttribute('minFilterId', `${limit.minFilterId}`);
213        cpuFreqLimitRow.setAttribute('cpu', `${limit.cpu}`);
214        cpuFreqLimitRow.isHover = true;
215        cpuFreqLimitRow.supplierFrame = () => {
216          return cpuFreqLimitSender(limit.maxFilterId, limit.minFilterId, limit.cpu, cpuFreqLimitRow).then((res) => {
217            res.forEach((item) => {
218              item.cpu = limit.cpu;
219            });
220            return res;
221          });
222        };
223        cpuFreqLimitRow.focusHandler = (ev) => {
224          this.trace.displayTip(
225            cpuFreqLimitRow,
226            CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct,
227            `<span>Max Freq: ${ColorUtils.formatNumberComma(
228              CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct?.max || 0
229            )} kHz</span><span>Min Freq: ${ColorUtils.formatNumberComma(
230              CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct?.min || 0
231            )} kHz</span>`
232          );
233        };
234        cpuFreqLimitRow.findHoverStruct = () => {
235          CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = cpuFreqLimitRow.getHoverStruct();
236        };
237        cpuFreqLimitRow.onThreadHandler = (useCache: boolean) => {
238          let context: CanvasRenderingContext2D;
239          if (cpuFreqLimitRow.currentContext) {
240            context = cpuFreqLimitRow.currentContext;
241          } else {
242            context = cpuFreqLimitRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
243          }
244          cpuFreqLimitRow.canvasSave(context);
245          (renders['cpu-limit-freq'] as CpuFreqLimitRender).renderMainThread(
246            {
247              context: context,
248              useCache: useCache,
249              type: `cpu-limit-freq-${limit.cpu}`,
250              cpu: limit.cpu,
251              maxFreq: findMax?.maxFreq || 0,
252              maxFreqName: findMax?.maxFreqName || '',
253            },
254            cpuFreqLimitRow
255          );
256          cpuFreqLimitRow.canvasRestore(context, this.trace);
257        };
258        this.folderRowLimit!.addChildTraceRow(cpuFreqLimitRow);
259      }
260    }
261  }
262}
263
264export class CpuFreqRowLimit {
265  cpu: number = 0;
266  maxFilterId: number = 0;
267  minFilterId: number = 0;
268}
269