• 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.js';
17import {
18  BaseStruct,
19  drawLines,
20  drawLoading,
21  drawSelection,
22  isFrameContainPoint,
23  ns2x,
24  Render,
25  drawFlagLine,
26  RequestMessage,
27  dataFilterHandler,
28} from './ProcedureWorkerCommon.js';
29import { TraceRow } from '../../component/trace/base/TraceRow.js';
30
31export class DiskIoAbilityRender extends Render {
32  renderMainThread(
33    req: {
34      context: CanvasRenderingContext2D;
35      useCache: boolean;
36      type: string;
37      maxDiskRate: number;
38      maxDiskRateName: string;
39    },
40    diskIoAbilityRow: TraceRow<DiskAbilityMonitorStruct>
41  ): void {
42    let diskIoAbilityList = diskIoAbilityRow.dataList;
43    let diskIoFilter = diskIoAbilityRow.dataListCache;
44    dataFilterHandler(diskIoAbilityList, diskIoFilter, {
45      startKey: 'startNS',
46      durKey: 'dur',
47      startNS: TraceRow.range?.startNS ?? 0,
48      endNS: TraceRow.range?.endNS ?? 0,
49      totalNS: TraceRow.range?.totalNS ?? 0,
50      frame: diskIoAbilityRow.frame,
51      paddingTop: 5,
52      useCache: req.useCache || !(TraceRow.range?.refresh ?? false),
53    });
54    req.context.beginPath();
55    let find = false;
56    for (let re of diskIoFilter) {
57      DiskAbilityMonitorStruct.draw(req.context, re, req.maxDiskRate, diskIoAbilityRow.isHover);
58      if (diskIoAbilityRow.isHover && re.frame &&
59        isFrameContainPoint(re.frame, diskIoAbilityRow.hoverX, diskIoAbilityRow.hoverY)
60      ) {
61        DiskAbilityMonitorStruct.hoverDiskAbilityStruct = re;
62        find = true;
63      }
64    }
65    if (!find && diskIoAbilityRow.isHover) {
66      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = undefined;
67    }
68    req.context.closePath();
69    let textMetrics = req.context.measureText(req.maxDiskRateName);
70    req.context.globalAlpha = 0.8;
71    req.context.fillStyle = '#f0f0f0';
72    req.context.fillRect(0, 5, textMetrics.width + 8, 18);
73    req.context.globalAlpha = 1;
74    req.context.fillStyle = '#333';
75    req.context.textBaseline = 'middle';
76    req.context.fillText(req.maxDiskRateName, 4, 5 + 9);
77  }
78
79  render(diskAbilityRequest: RequestMessage, diskIoAbilityList: Array<any>, filter: Array<any>) {
80    if (diskAbilityRequest.lazyRefresh) {
81      diskIoAbility(
82        diskIoAbilityList,
83        filter,
84        diskAbilityRequest.startNS,
85        diskAbilityRequest.endNS,
86        diskAbilityRequest.totalNS,
87        diskAbilityRequest.frame,
88        diskAbilityRequest.useCache || !diskAbilityRequest.range.refresh
89      );
90    } else {
91      if (!diskAbilityRequest.useCache) {
92        diskIoAbility(
93          diskIoAbilityList,
94          filter,
95          diskAbilityRequest.startNS,
96          diskAbilityRequest.endNS,
97          diskAbilityRequest.totalNS,
98          diskAbilityRequest.frame,
99          false
100        );
101      }
102    }
103    if (diskAbilityRequest.canvas) {
104      diskAbilityRequest.context.clearRect(0, 0, diskAbilityRequest.frame.width, diskAbilityRequest.frame.height);
105      let diskIoArr = filter;
106      if (
107        diskIoArr.length > 0 &&
108        !diskAbilityRequest.range.refresh &&
109        !diskAbilityRequest.useCache &&
110        diskAbilityRequest.lazyRefresh
111      ) {
112        drawLoading(
113          diskAbilityRequest.context,
114          diskAbilityRequest.startNS,
115          diskAbilityRequest.endNS,
116          diskAbilityRequest.totalNS,
117          diskAbilityRequest.frame,
118          diskIoArr[0].startNS,
119          diskIoArr[diskIoArr.length - 1].startNS + diskIoArr[diskIoArr.length - 1].dur
120        );
121      }
122      diskAbilityRequest.context.beginPath();
123      let maxDiskRate = diskAbilityRequest.params.maxDiskRate;
124      let maxDiskRateName = diskAbilityRequest.params.maxDiskRateName;
125      drawLines(
126        diskAbilityRequest.context,
127        diskAbilityRequest.xs,
128        diskAbilityRequest.frame.height,
129        diskAbilityRequest.lineColor
130      );
131      DiskAbilityMonitorStruct.hoverDiskAbilityStruct = undefined;
132      if (diskAbilityRequest.isHover) {
133        for (let re of filter) {
134          if (
135            re.frame &&
136            diskAbilityRequest.hoverX >= re.frame.x &&
137            diskAbilityRequest.hoverX <= re.frame.x + re.frame.width &&
138            diskAbilityRequest.hoverY >= re.frame.y &&
139            diskAbilityRequest.hoverY <= re.frame.y + re.frame.height
140          ) {
141            DiskAbilityMonitorStruct.hoverDiskAbilityStruct = re;
142            break;
143          }
144        }
145      }
146      DiskAbilityMonitorStruct.selectDiskAbilityStruct = diskAbilityRequest.params.selectDiskAbilityStruct;
147      for (let re of filter) {
148        DiskAbilityMonitorStruct.draw(diskAbilityRequest.context, re, maxDiskRate, true);
149      }
150      drawSelection(diskAbilityRequest.context, diskAbilityRequest.params);
151      diskAbilityRequest.context.closePath();
152      let textMetrics = diskAbilityRequest.context.measureText(maxDiskRateName);
153      diskAbilityRequest.context.globalAlpha = 0.8;
154      diskAbilityRequest.context.fillStyle = '#f0f0f0';
155      diskAbilityRequest.context.fillRect(0, 5, textMetrics.width + 8, 18);
156      diskAbilityRequest.context.globalAlpha = 1;
157      diskAbilityRequest.context.fillStyle = '#333';
158      diskAbilityRequest.context.textBaseline = 'middle';
159      diskAbilityRequest.context.fillText(maxDiskRateName, 4, 5 + 9);
160      drawFlagLine(
161        diskAbilityRequest.context,
162        diskAbilityRequest.flagMoveInfo,
163        diskAbilityRequest.flagSelectedInfo,
164        diskAbilityRequest.startNS,
165        diskAbilityRequest.endNS,
166        diskAbilityRequest.totalNS,
167        diskAbilityRequest.frame,
168        diskAbilityRequest.slicesTime
169      );
170    }
171    // @ts-ignore
172    self.postMessage({
173      id: diskAbilityRequest.id,
174      type: diskAbilityRequest.type,
175      results: diskAbilityRequest.canvas ? undefined : filter,
176      hover: DiskAbilityMonitorStruct.hoverDiskAbilityStruct,
177    });
178  }
179}
180
181export function diskIoAbility(
182  diskIoAbilityList: Array<any>,
183  res: Array<any>,
184  startNS: number,
185  endNS: number,
186  totalNS: number,
187  frame: any,
188  use: boolean
189) {
190  if (use && res.length > 0) {
191    for (let i = 0; i < res.length; i++) {
192      let diskIoAbilityItem = res[i];
193      if (
194        (diskIoAbilityItem.startNS || 0) + (diskIoAbilityItem.dur || 0) > (startNS || 0) &&
195        (diskIoAbilityItem.startNS || 0) < (endNS || 0)
196      ) {
197        DiskAbilityMonitorStruct.setDiskIOFrame(diskIoAbilityItem, 5, startNS || 0, endNS || 0, totalNS || 0, frame);
198      } else {
199        diskIoAbilityItem.frame = null;
200      }
201    }
202    return;
203  }
204  res.length = 0;
205  if (diskIoAbilityList) {
206    for (let index = 0; index < diskIoAbilityList.length; index++) {
207      let item = diskIoAbilityList[index];
208      if (index === diskIoAbilityList.length - 1) {
209        item.dur = (endNS || 0) - (item.startNS || 0);
210      } else {
211        item.dur = (diskIoAbilityList[index + 1].startNS || 0) - (item.startNS || 0);
212      }
213      if ((item.startNS || 0) + (item.dur || 0) > (startNS || 0) && (item.startNS || 0) < (endNS || 0)) {
214        DiskAbilityMonitorStruct.setDiskIOFrame(
215          diskIoAbilityList[index],
216          5,
217          startNS || 0,
218          endNS || 0,
219          totalNS || 0,
220          frame
221        );
222        if (
223          index > 0 &&
224          (diskIoAbilityList[index - 1].frame?.x || 0) == (diskIoAbilityList[index].frame?.x || 0) &&
225          (diskIoAbilityList[index - 1].frame?.width || 0) == (diskIoAbilityList[index].frame?.width || 0)
226        ) {
227        } else {
228          res.push(item);
229        }
230      }
231    }
232  }
233}
234
235export class DiskAbilityMonitorStruct extends BaseStruct {
236  static maxDiskRate: number = 0;
237  static maxDiskRateName: string = '0 KB/S';
238  static hoverDiskAbilityStruct: DiskAbilityMonitorStruct | undefined;
239  static selectDiskAbilityStruct: DiskAbilityMonitorStruct | undefined;
240  value: number | undefined;
241  startNS: number | undefined;
242  dur: number | undefined; //自补充,数据库没有返回
243
244  static draw(
245    diskIoAbilityContext: CanvasRenderingContext2D,
246    diskIoAbilityData: DiskAbilityMonitorStruct,
247    maxDiskRate: number,
248    isHover: boolean
249  ) {
250    if (diskIoAbilityData.frame) {
251      let width = diskIoAbilityData.frame.width || 0;
252      let index = 2;
253      diskIoAbilityContext.fillStyle = ColorUtils.colorForTid(index);
254      diskIoAbilityContext.strokeStyle = ColorUtils.colorForTid(index);
255      if (diskIoAbilityData.startNS === DiskAbilityMonitorStruct.hoverDiskAbilityStruct?.startNS && isHover) {
256        diskIoAbilityContext.lineWidth = 1;
257        diskIoAbilityContext.globalAlpha = 0.6;
258        let drawHeight: number = Math.floor(((diskIoAbilityData.value || 0) * (diskIoAbilityData.frame.height || 0) * 1.0) / maxDiskRate);
259        diskIoAbilityContext.fillRect(
260          diskIoAbilityData.frame.x,
261          diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4,
262          width,
263          drawHeight
264        );
265        diskIoAbilityContext.beginPath();
266        diskIoAbilityContext.arc(
267          diskIoAbilityData.frame.x,
268          diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4,
269          3,
270          0,
271          2 * Math.PI,
272          true
273        );
274        diskIoAbilityContext.fill();
275        diskIoAbilityContext.globalAlpha = 1.0;
276        diskIoAbilityContext.stroke();
277        diskIoAbilityContext.beginPath();
278        diskIoAbilityContext.moveTo(diskIoAbilityData.frame.x + 3, diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4);
279        diskIoAbilityContext.lineWidth = 3;
280        diskIoAbilityContext.lineTo(diskIoAbilityData.frame.x + width, diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4);
281        diskIoAbilityContext.stroke();
282      } else {
283        diskIoAbilityContext.globalAlpha = 0.6;
284        diskIoAbilityContext.lineWidth = 1;
285        let drawHeight: number = Math.floor(((diskIoAbilityData.value || 0) * (diskIoAbilityData.frame.height || 0)) / maxDiskRate);
286        diskIoAbilityContext.fillRect(
287          diskIoAbilityData.frame.x,
288          diskIoAbilityData.frame.y + diskIoAbilityData.frame.height - drawHeight + 4,
289          width,
290          drawHeight
291        );
292      }
293    }
294    diskIoAbilityContext.globalAlpha = 1.0;
295    diskIoAbilityContext.lineWidth = 1;
296  }
297
298  static setDiskIOFrame(diskIONode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any) {
299    let diskIOStartPointX: number, diskIOEndPointX: number;
300
301    if ((diskIONode.startNS || 0) < startNS) {
302      diskIOStartPointX = 0;
303    } else {
304      diskIOStartPointX = ns2x(diskIONode.startNS || 0, startNS, endNS, totalNS, frame);
305    }
306    if ((diskIONode.startNS || 0) + (diskIONode.dur || 0) > endNS) {
307      diskIOEndPointX = frame.width;
308    } else {
309      diskIOEndPointX = ns2x((diskIONode.startNS || 0) + (diskIONode.dur || 0), startNS, endNS, totalNS, frame);
310    }
311    let frameWidth: number = diskIOEndPointX - diskIOStartPointX <= 1 ? 1 : diskIOEndPointX - diskIOStartPointX;
312    if (!diskIONode.frame) {
313      diskIONode.frame = {};
314    }
315    diskIONode.frame.x = Math.floor(diskIOStartPointX);
316    diskIONode.frame.y = frame.y + padding;
317    diskIONode.frame.width = Math.ceil(frameWidth);
318    diskIONode.frame.height = Math.floor(frame.height - padding * 2);
319  }
320}
321