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