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