• 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 { TraceRow } from '../../component/trace/base/TraceRow';
18import { isFrameContainPoint, Render, mem, drawLoadingFrame } from './ProcedureWorkerCommon';
19import { ProcessMemStruct as BaseProcessMemStruct } from '../../bean/ProcessMemStruct';
20export class MemRender {
21  renderMainThread(
22    req: {
23      useCache: boolean;
24      context: CanvasRenderingContext2D;
25      type: string;
26    },
27    row: TraceRow<ProcessMemStruct>
28  ): void {
29    let memList = row.dataList;
30    let memFilter = row.dataListCache;
31    mem(
32      memList,
33      memFilter,
34      TraceRow.range!.startNS,
35      TraceRow.range!.endNS,
36      TraceRow.range!.totalNS,
37      row.frame,
38      req.useCache || !TraceRow.range!.refresh
39    );
40    drawLoadingFrame(req.context, memFilter, row);
41    req.context.beginPath();
42    let memFind = false;
43    for (let re of memFilter) {
44      ProcessMemStruct.draw(req.context, re);
45      if (row.isHover) {
46        if (re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) {
47          ProcessMemStruct.hoverProcessMemStruct = re;
48          memFind = true;
49        }
50      }
51    }
52    if (!memFind && row.isHover) {
53      ProcessMemStruct.hoverProcessMemStruct = undefined;
54    }
55    req.context.closePath();
56  }
57}
58
59export class ProcessMemStruct extends BaseProcessMemStruct {
60  static draw(memContext: CanvasRenderingContext2D, data: ProcessMemStruct): void {
61    if (data.frame) {
62      let width = data.frame.width || 0;
63      memContext.fillStyle = ColorUtils.colorForTid(data.maxValue || 0);
64      memContext.strokeStyle = ColorUtils.colorForTid(data.maxValue || 0);
65      data.maxValue = data.maxValue === 0 ? 1 : data.maxValue;
66      if ((data.value || 0) < 0) {
67        memContext.fillStyle = ColorUtils.colorForTid(data.minValue || 0);
68        memContext.strokeStyle = ColorUtils.colorForTid(data.minValue || 0);
69      }
70      let drawHeight: number = Math.floor(((data.value || 0) * (data.frame.height || 0) * 1.0) / data.maxValue!);
71      if (drawHeight === 0) {
72        drawHeight = 1;
73      }
74      let minHeight: number = 0;
75      let maxHeight: number = 0;
76      let sumHeight: number = 0;
77      let cutHeight: number = 0;
78      if (data.minValue! < 0) {
79        minHeight = Math.floor(((data.minValue || 0) * (data.frame.height || 0) * 1.0) / data.maxValue!);
80        maxHeight = Math.floor(((data.maxValue || 0) * (data.frame.height || 0) * 1.0) / data.maxValue!);
81        sumHeight = Math.abs(minHeight) + Math.abs(maxHeight);
82        let num = this.cal(Math.abs(minHeight), Math.abs(maxHeight));
83        drawHeight = Math.floor(drawHeight / num);
84        cutHeight = Math.abs(Math.floor(((data.minValue || 0) * (data.frame.height || 0) * 1.0) / data.maxValue!) / num) + 1;
85        if (data.maxValue! < 0) {
86          drawHeight = -drawHeight;
87          cutHeight = 30;
88        }
89      }
90      if (data === ProcessMemStruct.hoverProcessMemStruct) {
91        memContext.lineWidth = 1;
92        memContext.globalAlpha = 0.6;
93        memContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight - cutHeight, width, drawHeight);
94        memContext.beginPath();
95        memContext.arc(data.frame.x, data.frame.y + data.frame.height - drawHeight - cutHeight, 3, 0, 2 * Math.PI, true);
96        memContext.fill();
97        memContext.globalAlpha = 1.0;
98        memContext.stroke();
99        memContext.closePath();
100        memContext.beginPath();
101        memContext.moveTo(data.frame.x + 3, data.frame.y + data.frame.height - drawHeight - cutHeight);
102        memContext.lineWidth = 3;
103        memContext.lineTo(data.frame.x + width, data.frame.y + data.frame.height - drawHeight - cutHeight);
104        memContext.stroke();
105        memContext.closePath();
106      } else {
107        memContext.globalAlpha = 0.6;
108        memContext.lineWidth = 1;
109        memContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight - cutHeight, width, drawHeight);
110        if (width > 2) {
111          memContext.lineWidth = 1;
112          memContext.globalAlpha = 1.0;
113          memContext.strokeRect(data.frame.x, data.frame.y + data.frame.height - drawHeight - cutHeight, width, drawHeight);
114        }
115      }
116    }
117    memContext.globalAlpha = 1.0;
118    memContext.lineWidth = 1;
119  }
120
121  static cal(minHeight: number, maxHeight: number): number {
122    let multiplier = 1;
123    let newSum: number;
124    do {
125      newSum = minHeight / multiplier + maxHeight / multiplier;
126      multiplier += 2;
127    } while (newSum > 30 && multiplier <= (minHeight + maxHeight) * 2);
128    if (newSum <= 30) {
129      multiplier -= 2;
130      while (minHeight / (multiplier + 2) + maxHeight / (multiplier + 2) > 30) {
131        multiplier += 2;
132      }
133      return multiplier;
134    } else {
135      return 2;
136    }
137  }
138}
139