• 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 {
18  BaseStruct,
19  dataFilterHandler,
20  Render,
21  isFrameContainPoint,
22  ns2x,
23  drawLoadingFrame,
24} from './ProcedureWorkerCommon';
25import { TraceRow } from '../../component/trace/base/TraceRow';
26
27export class MemoryAbilityRender extends Render {
28  renderMainThread(
29    req: {
30      context: CanvasRenderingContext2D;
31      useCache: boolean;
32      type: string;
33      maxMemoryByte: number;
34      maxMemoryByteName: string;
35    },
36    memoryAbilityRow: TraceRow<MemoryAbilityMonitorStruct>
37  ): void {
38    let memoryAbilityList = memoryAbilityRow.dataList;
39    let memoryAbilityFilter = memoryAbilityRow.dataListCache;
40    dataFilterHandler(memoryAbilityList, memoryAbilityFilter, {
41      startKey: 'startNS',
42      durKey: 'dur',
43      startNS: TraceRow.range?.startNS ?? 0,
44      endNS: TraceRow.range?.endNS ?? 0,
45      totalNS: TraceRow.range?.totalNS ?? 0,
46      frame: memoryAbilityRow.frame,
47      paddingTop: 5,
48      useCache: req.useCache || !(TraceRow.range?.refresh ?? false),
49    });
50    drawLoadingFrame(req.context, memoryAbilityRow.dataListCache, memoryAbilityRow);
51    req.context.beginPath();
52    let find = false;
53    for (let re of memoryAbilityFilter) {
54      MemoryAbilityMonitorStruct.draw(req.context, re, req.maxMemoryByte, memoryAbilityRow.isHover);
55      if (
56        memoryAbilityRow.isHover &&
57        re.frame &&
58        isFrameContainPoint(re.frame, memoryAbilityRow.hoverX, memoryAbilityRow.hoverY)
59      ) {
60        MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = re;
61        find = true;
62      }
63    }
64    if (!find && memoryAbilityRow.isHover) {
65      MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = undefined;
66    }
67    req.context.closePath();
68    let textMetrics = req.context.measureText(req.maxMemoryByteName);
69    req.context.globalAlpha = 0.8;
70    req.context.fillStyle = '#f0f0f0';
71    req.context.fillRect(0, 5, textMetrics.width + 8, 18);
72    req.context.globalAlpha = 1;
73    req.context.fillStyle = '#333';
74    req.context.textBaseline = 'middle';
75    req.context.fillText(req.maxMemoryByteName, 4, 5 + 9);
76  }
77}
78
79export function memoryAbility(
80  memoryAbilityList: Array<any>,
81  res: Array<any>,
82  startNS: number,
83  endNS: number,
84  totalNS: number,
85  frame: any,
86  use: boolean
87) {
88  if (use && res.length > 0) {
89    for (let i = 0; i < res.length; i++) {
90      let memoryAbilityItem = res[i];
91      if (
92        (memoryAbilityItem.startNS || 0) + (memoryAbilityItem.dur || 0) > startNS &&
93        (memoryAbilityItem.startNS || 0) < endNS
94      ) {
95        MemoryAbilityMonitorStruct.setMemoryFrame(memoryAbilityItem, 5, startNS, endNS, totalNS, frame);
96      } else {
97        memoryAbilityItem.frame = null;
98      }
99    }
100    return;
101  }
102  res.length = 0;
103  setMemoryAbility(memoryAbilityList, res, startNS, endNS, totalNS, frame);
104}
105function setMemoryAbility(
106  memoryAbilityList: Array<any>,
107  res: Array<any>,
108  startNS: number,
109  endNS: number,
110  totalNS: number,
111  frame: any
112) {
113  if (memoryAbilityList) {
114    for (let memoryAbilityIndex = 0; memoryAbilityIndex < memoryAbilityList.length; memoryAbilityIndex++) {
115      let item = memoryAbilityList[memoryAbilityIndex];
116      item.dur =
117        memoryAbilityIndex === memoryAbilityList.length - 1
118          ? (endNS || 0) - (item.startNS || 0)
119          : (memoryAbilityList[memoryAbilityIndex + 1].startNS || 0) - (item.startNS || 0);
120      if ((item.startNS || 0) + (item.dur || 0) > startNS && (item.startNS || 0) < endNS) {
121        MemoryAbilityMonitorStruct.setMemoryFrame(item, 5, startNS, endNS, totalNS, frame);
122        if (
123          !(
124            memoryAbilityIndex > 0 &&
125            (memoryAbilityList[memoryAbilityIndex - 1].frame.x || 0) == (item.frame.x || 0) &&
126            (memoryAbilityList[memoryAbilityIndex - 1].frame.width || 0) == (item.frame.width || 0)
127          )
128        ) {
129          res.push(item);
130        }
131      }
132    }
133  }
134}
135
136export class MemoryAbilityMonitorStruct extends BaseStruct {
137  static maxMemoryByte: number = 0;
138  static maxMemoryByteName: string = '0 MB';
139  static hoverMemoryAbilityStruct: MemoryAbilityMonitorStruct | undefined;
140  static selectMemoryAbilityStruct: MemoryAbilityMonitorStruct | undefined;
141  cpu: number | undefined;
142  value: number | undefined;
143  startNS: number | undefined;
144  dur: number | undefined;
145
146  static draw(
147    memoryAbilityContext2D: CanvasRenderingContext2D,
148    memoryAbilityData: MemoryAbilityMonitorStruct,
149    maxMemoryByte: number,
150    isHover: boolean
151  ) {
152    if (memoryAbilityData.frame) {
153      let width = memoryAbilityData.frame.width || 0;
154      let index = 2;
155      memoryAbilityContext2D.fillStyle = ColorUtils.colorForTid(index);
156      memoryAbilityContext2D.strokeStyle = ColorUtils.colorForTid(index);
157      let drawHeight: number = Math.floor(
158        ((memoryAbilityData.value || 0) * (memoryAbilityData.frame.height || 0) * 1.0) / maxMemoryByte
159      );
160      let y = memoryAbilityData.frame.y + memoryAbilityData.frame.height - drawHeight + 4;
161      if (memoryAbilityData.startNS === MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct?.startNS && isHover) {
162        memoryAbilityContext2D.lineWidth = 1;
163        memoryAbilityContext2D.globalAlpha = 0.6;
164        memoryAbilityContext2D.fillRect(memoryAbilityData.frame.x, y, width, drawHeight);
165        memoryAbilityContext2D.beginPath();
166        memoryAbilityContext2D.arc(memoryAbilityData.frame.x, y, 3, 0, 2 * Math.PI, true);
167        memoryAbilityContext2D.fill();
168        memoryAbilityContext2D.globalAlpha = 1.0;
169        memoryAbilityContext2D.stroke();
170        memoryAbilityContext2D.beginPath();
171        memoryAbilityContext2D.moveTo(memoryAbilityData.frame.x + 3, y);
172        memoryAbilityContext2D.lineWidth = 3;
173        memoryAbilityContext2D.lineTo(memoryAbilityData.frame.x + width, y);
174        memoryAbilityContext2D.stroke();
175      } else {
176        memoryAbilityContext2D.globalAlpha = 0.6;
177        memoryAbilityContext2D.lineWidth = 1;
178        let drawHeight: number = Math.floor(
179          ((memoryAbilityData.value || 0) * (memoryAbilityData.frame.height || 0)) / maxMemoryByte
180        );
181        memoryAbilityContext2D.fillRect(memoryAbilityData.frame.x, y, width, drawHeight);
182      }
183    }
184    memoryAbilityContext2D.globalAlpha = 1.0;
185    memoryAbilityContext2D.lineWidth = 1;
186  }
187
188  static setMemoryFrame(memoryNode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any) {
189    let memoryStartPointX: number, memoryEndPointX: number;
190
191    if ((memoryNode.startNS || 0) < startNS) {
192      memoryStartPointX = 0;
193    } else {
194      memoryStartPointX = ns2x(memoryNode.startNS || 0, startNS, endNS, totalNS, frame);
195    }
196    if ((memoryNode.startNS || 0) + (memoryNode.dur || 0) > endNS) {
197      memoryEndPointX = frame.width;
198    } else {
199      memoryEndPointX = ns2x((memoryNode.startNS || 0) + (memoryNode.dur || 0), startNS, endNS, totalNS, frame);
200    }
201    let frameWidth: number = memoryEndPointX - memoryStartPointX <= 1 ? 1 : memoryEndPointX - memoryStartPointX;
202    if (!memoryNode.frame) {
203      memoryNode.frame = {};
204    }
205    memoryNode.frame.x = Math.floor(memoryStartPointX);
206    memoryNode.frame.y = frame.y + padding;
207    memoryNode.frame.width = Math.ceil(frameWidth);
208    memoryNode.frame.height = Math.floor(frame.height - padding * 2);
209  }
210}
211
212const textPadding = 2;
213