• 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 { ColorUtils } from '../../../component/trace/base/ColorUtils';
17import { HiPerfStruct, PerfRender, type RequestMessage } from '../ProcedureWorkerCommon';
18
19import { TraceRow } from '../../../component/trace/base/TraceRow';
20
21export class HiperfReportRender extends PerfRender {
22  renderMainThread(hiPerfReportReq: any, row: TraceRow<HiPerfReportStruct>): void {
23    let list = row.dataList;
24    let filter = row.dataListCache;
25    let groupBy10MS = hiPerfReportReq.scale > 30_000_000;
26    if (list && row.dataList2.length === 0) {
27      row.dataList2 = HiPerfReportStruct.reportGroupBy10MS(list, hiPerfReportReq.intervalPerf);
28    }
29    HiPerfReport(
30      list,
31      row.dataList2,
32      hiPerfReportReq.type!,
33      filter,
34      TraceRow.range?.startNS ?? 0,
35      TraceRow.range?.endNS ?? 0,
36      TraceRow.range?.totalNS ?? 0,
37      row.frame,
38      groupBy10MS,
39      hiPerfReportReq.intervalPerf,
40      hiPerfReportReq.useCache || (TraceRow.range?.refresh ?? false)
41    );
42    drawHiperfReportRender(hiPerfReportReq, groupBy10MS, filter, row);
43  }
44
45  render(hiPerfReportRequest: RequestMessage, list: Array<any>, filter: Array<any>, dataList2: Array<any>): void {}
46}
47
48function drawHiperfReportRender(
49  hiPerfReportReq: any,
50  groupBy10MS: boolean,
51  filter: HiPerfReportStruct[],
52  row: TraceRow<HiPerfReportStruct>
53) {
54  hiPerfReportReq.context.beginPath();
55  hiPerfReportReq.context.fillStyle = ColorUtils.FUNC_COLOR[0];
56  hiPerfReportReq.context.strokeStyle = ColorUtils.FUNC_COLOR[0];
57  let normalPath = new Path2D();
58  let specPath = new Path2D();
59  let offset = groupBy10MS ? 0 : 3;
60  let find = false;
61  for (let re of filter) {
62    HiPerfReportStruct.draw(hiPerfReportReq.context, normalPath, specPath, re, groupBy10MS);
63    if (row.isHover) {
64      if (re.frame && row.hoverX >= re.frame.x - offset && row.hoverX <= re.frame.x + re.frame.width + offset) {
65        HiPerfReportStruct.hoverStruct = re;
66        find = true;
67      }
68    }
69  }
70  if (!find && row.isHover) {
71    HiPerfReportStruct.hoverStruct = undefined;
72  }
73  if (groupBy10MS) {
74    hiPerfReportReq.context.fill(normalPath);
75  } else {
76    hiPerfReportReq.context.stroke(normalPath);
77    HiPerfStruct.drawSpecialPath(hiPerfReportReq.context, specPath);
78  }
79  hiPerfReportReq.context.closePath();
80}
81
82function setFrameByfilter(startNS: number, endNS: number, frame: any, hiPerfFilters: Array<any>): void {
83  let pns = (endNS - startNS) / frame.width;
84  let y = frame.y;
85  for (let i = 0; i < hiPerfFilters.length; i++) {
86    let hiPerfData = hiPerfFilters[i];
87    if ((hiPerfData.startNS || 0) + (hiPerfData.dur || 0) > startNS && (hiPerfData.startNS || 0) < endNS) {
88      if (!hiPerfData.frame) {
89        hiPerfData.frame = {};
90        hiPerfData.frame.y = y;
91      }
92      hiPerfData.frame.height = hiPerfData.height;
93      HiPerfReportStruct.setFrame(hiPerfData, pns, startNS, endNS, frame);
94    } else {
95      hiPerfData.frame = null;
96    }
97  }
98}
99
100function setFrameByArr(
101  groupBy10MS: boolean,
102  arr2: any,
103  arr: Array<any>,
104  hiPerfFilters: Array<any>,
105  startNS: number,
106  endNS: number,
107  frame: any
108): void {
109  let list: Array<any> = groupBy10MS ? arr2 : arr;
110  let pns = (endNS - startNS) / frame.width;
111  let y = frame.y;
112  list
113    .filter((it) => (it.startNS || 0) + (it.dur || 0) > startNS && (it.startNS || 0) < endNS)
114    .map((it) => {
115      if (!it.frame) {
116        it.frame = {};
117        it.frame.y = y;
118      }
119      it.frame.height = it.height;
120      HiPerfReportStruct.setFrame(it, pns, startNS, endNS, frame);
121      return it;
122    })
123    .reduce((pre, current, index, arr) => {
124      if (!pre[`${current.frame.x}`]) {
125        pre[`${current.frame.x}`] = [];
126        pre[`${current.frame.x}`].push(current);
127        if (groupBy10MS) {
128          hiPerfFilters.push(current);
129        } else {
130          if (hiPerfFilters.length === 0) {
131            hiPerfFilters.push(current);
132          }
133          if (
134            hiPerfFilters[hiPerfFilters.length - 1] &&
135            Math.abs(current.frame.x - hiPerfFilters[hiPerfFilters.length - 1].frame.x) > 4
136          ) {
137            hiPerfFilters.push(current);
138          }
139        }
140      }
141      return pre;
142    }, {});
143}
144
145export function HiPerfReport(
146  arr: Array<any>,
147  arr2: any,
148  type: string,
149  hiPerfFilters: Array<any>,
150  startNS: number,
151  endNS: number,
152  totalNS: number,
153  frame: any,
154  groupBy10MS: boolean,
155  intervalPerf: number,
156  use: boolean
157): void {
158  if (use && hiPerfFilters.length > 0) {
159    setFrameByfilter(endNS, startNS, frame, hiPerfFilters);
160    return;
161  }
162  hiPerfFilters.length = 0;
163  if (arr) {
164    setFrameByArr(groupBy10MS, arr2, arr, hiPerfFilters, startNS, endNS, frame);
165  }
166}
167
168export class HiPerfReportStruct extends HiPerfStruct {
169  static hoverStruct: HiPerfReportStruct | undefined;
170  static selectStruct: HiPerfReportStruct | undefined;
171
172  static reportGroupBy10MS(array: Array<any>, intervalPerf: number): Array<any> {
173    let obj = array
174      .map((it) => {
175        it.timestamp_group = Math.trunc(it.startNS / 1_000_000_0) * 1_000_000_0;
176        return it;
177      })
178      .reduce((pre, current) => {
179        (pre[current['timestamp_group']] = pre[current['timestamp_group']] || []).push(current);
180        return pre;
181      }, {});
182    let reportArr: any[] = [];
183    let max = 0;
184    for (let aKey in obj) {
185      let sum = obj[aKey].reduce((pre: any, cur: any) => {
186        return pre + cur.event_count;
187      }, 0);
188      if (sum > max) max = sum;
189      let ns = parseInt(aKey);
190      reportArr.push({
191        startNS: ns,
192        dur: 1_000_000_0,
193        height: 0,
194        sum: sum,
195      });
196    }
197    reportArr.map((it) => {
198      it.height = Math.floor((40 * it.sum) / max);
199      return it;
200    });
201    return reportArr;
202  }
203}
204