• 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 { BaseStruct, Rect, isFrameContainPoint } from './ProcedureWorkerCommon.js';
16import { TraceRow } from '../../component/trace/base/TraceRow.js';
17import { HeapSample } from '../../../js-heap/model/DatabaseStruct.js';
18
19export class HeapTimelineRender {
20  renderMainThread(
21    req: {
22      context: CanvasRenderingContext2D;
23      useCache: boolean;
24      type: string;
25      samples: Array<HeapSample>;
26    },
27    row: TraceRow<HeapTimelineStruct>
28  ) {
29    let list = row.dataList;
30    let filter = row.dataListCache;
31    HeapTimelineStruct.samples = req.samples;
32    HeapTimeline(
33      list,
34      filter,
35      HeapTimelineStruct.samples,
36      TraceRow.range?.startNS ?? 0,
37      TraceRow.range?.endNS ?? 0,
38      (TraceRow.range?.endNS ?? 0) - (TraceRow.range?.startNS! ?? 0),
39      row.frame
40    );
41    let heapTimelineFind = false;
42    for (let re of filter) {
43      HeapTimelineStruct.draw(req.context, re);
44      if (row.isHover) {
45        if (re.size === 0) {
46          if (
47            re.frame &&
48            row.hoverX >= re.frame.x &&
49            row.hoverX <= re.frame.x &&
50            row.hoverY >= re.frame.y &&
51            row.hoverY <= re.frame.y + re.frame.height
52          ) {
53            HeapTimelineStruct.hoverHeapTimelineStruct = re;
54            heapTimelineFind = true;
55          }
56        } else {
57          if (re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) {
58            HeapTimelineStruct.hoverHeapTimelineStruct = re;
59            heapTimelineFind = true;
60          }
61        }
62      }
63    }
64    if (!heapTimelineFind && row.isHover) HeapTimelineStruct.hoverHeapTimelineStruct = undefined;
65  }
66}
67export function HeapTimeline(
68  list: Array<any>,
69  filter: Array<any>,
70  samples: Array<HeapSample>,
71  startNS: number,
72  endNS: number,
73  totalNS: number,
74  frame: any
75) {
76  let maxSize = 0;
77  let index = [];
78
79  for (let i = 1; i < samples.length; i++) {
80    if (samples[i].size > 0) {
81      maxSize = Math.max(maxSize, samples[i].size);
82      index.push(i);
83    }
84  }
85  filter.length = 0;
86  for (let i of index) {
87    HeapTimelineStruct.setFrame(
88      samples[i].timestamp,
89      samples[i].size,
90      maxSize,
91      list[i],
92      startNS || 0,
93      endNS || 0,
94      totalNS || 0,
95      frame
96    );
97  }
98  for (let i = 0, len = list.length; i < len; i++) {
99    if (list[i].frame) {
100      filter.push(list[i]);
101    }
102  }
103}
104export class HeapTimelineStruct extends BaseStruct {
105  static hoverHeapTimelineStruct: HeapTimelineStruct | undefined;
106  static samples: Array<HeapSample>;
107  size: number = 0;
108
109  static setFrame(
110    timestamp: number,
111    size: number,
112    maxSize: number,
113    node: any,
114    startNS: number,
115    endNS: number,
116    totalNS: number,
117    frame: Rect
118  ) {
119    node.frame = null;
120    // us * 1000 = ns
121    if (node.timestamp * 1000 > startNS && node.timestamp * 1000 < endNS && node.timestamp == timestamp) {
122      let rectangle: Rect = new Rect(
123        Math.floor(((timestamp * 1000 - startNS) / totalNS) * frame.width),
124        0,
125        2,
126        Math.floor((size / maxSize) * frame.height) < 1 ? 1 : Math.floor((size / maxSize) * frame.height)
127      );
128      node.frame = rectangle;
129    }
130  }
131
132  static draw(ctx: CanvasRenderingContext2D, node: HeapTimelineStruct): void {
133    ctx!.beginPath();
134    ctx!.lineWidth = 2;
135    ctx!.strokeStyle = '#0A59F7';
136    ctx!.moveTo(node.frame!.x, 40);
137    ctx!.lineTo(node.frame!.x, 40 - node.frame!.height);
138    ctx!.stroke();
139    ctx!.closePath();
140  }
141}
142