• 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  dataFilterHandler,
20  isFrameContainPoint,
21  ns2x,
22  RequestMessage,
23  Render,
24} from './ProcedureWorkerCommon.js';
25import { TraceRow } from '../../component/trace/base/TraceRow.js';
26import { DiskAbilityMonitorStruct } from './ProcedureWorkerDiskIoAbility.js';
27
28export class CpuAbilityRender extends Render {
29  renderMainThread(
30    req: {
31      context: CanvasRenderingContext2D;
32      useCache: boolean;
33      type: string;
34      maxCpuUtilization: number;
35      maxCpuUtilizationName: string;
36    },
37    cpuAbilityRow: TraceRow<CpuAbilityMonitorStruct>
38  ): void {
39    let cpuAbilityList = cpuAbilityRow.dataList;
40    let cpuAbilityFilter = cpuAbilityRow.dataListCache;
41    dataFilterHandler(cpuAbilityList, cpuAbilityFilter, {
42      startKey: 'startNS',
43      durKey: 'dur',
44      startNS: TraceRow.range?.startNS ?? 0,
45      endNS: TraceRow.range?.endNS ?? 0,
46      totalNS: TraceRow.range?.totalNS ?? 0,
47      frame: cpuAbilityRow.frame,
48      paddingTop: 5,
49      useCache: req.useCache || !(TraceRow.range?.refresh ?? false),
50    });
51    let find = false;
52    req.context.beginPath();
53    for (let re of cpuAbilityFilter) {
54      CpuAbilityMonitorStruct.draw(req.context, re, req.maxCpuUtilization, cpuAbilityRow.isHover);
55      if (cpuAbilityRow.isHover && re.frame &&
56        isFrameContainPoint(re.frame, cpuAbilityRow.hoverX, cpuAbilityRow.hoverY)
57      ) {
58        CpuAbilityMonitorStruct.hoverCpuAbilityStruct = re;
59        find = true;
60      }
61    }
62    if (!find && cpuAbilityRow.isHover) {
63      CpuAbilityMonitorStruct.hoverCpuAbilityStruct = undefined;
64    }
65    req.context.closePath();
66    let textMetrics = req.context.measureText(req.maxCpuUtilizationName);
67    req.context.globalAlpha = 0.8;
68    req.context.fillStyle = '#f0f0f0';
69    req.context.fillRect(0, 5, textMetrics.width + 8, 18);
70    req.context.globalAlpha = 1;
71    req.context.fillStyle = '#333';
72    req.context.textBaseline = 'middle';
73    req.context.fillText(req.maxCpuUtilizationName, 4, 5 + 9);
74  }
75
76  render(req: RequestMessage, list: Array<any>, filter: Array<any>) {}
77}
78
79export function cpuAbility(
80  cpuAbilityList: Array<any>,
81  cpuAbilityFilters: Array<any>,
82  startNS: number,
83  endNS: number,
84  totalNS: number,
85  frame: any,
86  use: boolean
87) {
88  if (use && cpuAbilityFilters.length > 0) {
89    for (let index = 0; index < cpuAbilityFilters.length; index++) {
90      let item = cpuAbilityFilters[index];
91      if ((item.startNS || 0) + (item.dur || 0) > (startNS || 0) && (item.startNS || 0) < (endNS || 0)) {
92        CpuAbilityMonitorStruct.setCpuAbilityFrame(cpuAbilityFilters[index], 5, startNS || 0, endNS || 0, totalNS || 0, frame);
93      } else {
94        cpuAbilityFilters[index].frame = null;
95      }
96    }
97    return;
98  }
99  cpuAbilityFilters.length = 0;
100  if (cpuAbilityList) {
101    for (let cpuAbilityIndex = 0; cpuAbilityIndex < cpuAbilityList.length; cpuAbilityIndex++) {
102      let item = cpuAbilityList[cpuAbilityIndex];
103      if (cpuAbilityIndex === cpuAbilityList.length - 1) {
104        item.dur = (endNS || 0) - (item.startNS || 0);
105      } else {
106        item.dur = (cpuAbilityList[cpuAbilityIndex + 1].startNS || 0) - (item.startNS || 0);
107      }
108      if ((item.startNS || 0) + (item.dur || 0) > (startNS || 0) && (item.startNS || 0) < (endNS || 0)) {
109        CpuAbilityMonitorStruct.setCpuAbilityFrame(
110          cpuAbilityList[cpuAbilityIndex],
111          5,
112          startNS || 0,
113          endNS || 0,
114          totalNS || 0,
115          frame
116        );
117        if (
118          cpuAbilityIndex > 0 &&
119          (cpuAbilityList[cpuAbilityIndex - 1].frame?.x || 0) == (cpuAbilityList[cpuAbilityIndex].frame?.x || 0) &&
120          (cpuAbilityList[cpuAbilityIndex - 1].frame?.width || 0) == (cpuAbilityList[cpuAbilityIndex].frame?.width || 0)
121        ) {
122        } else {
123          cpuAbilityFilters.push(item);
124        }
125      }
126    }
127  }
128}
129
130export class CpuAbilityMonitorStruct extends BaseStruct {
131  static maxCpuUtilization: number = 0;
132  static maxCpuUtilizationName: string = '0 %';
133  static hoverCpuAbilityStruct: CpuAbilityMonitorStruct | undefined;
134  static selectCpuAbilityStruct: CpuAbilityMonitorStruct | undefined;
135
136  type: number | undefined;
137  value: number | undefined;
138  startNS: number | undefined;
139  dur: number | undefined; //自补充,数据库没有返回
140
141  static draw(
142    cpuAbilityContext2D: CanvasRenderingContext2D,
143    cpuAbilityData: CpuAbilityMonitorStruct,
144    maxCpuUtilization: number,
145    isHover: boolean
146  ) {
147    if (cpuAbilityData.frame) {
148      let width = cpuAbilityData.frame.width || 0;
149      let index = 2;
150      cpuAbilityContext2D.fillStyle = ColorUtils.colorForTid(index);
151      cpuAbilityContext2D.strokeStyle = ColorUtils.colorForTid(index);
152      if (cpuAbilityData.startNS === CpuAbilityMonitorStruct.hoverCpuAbilityStruct?.startNS && isHover) {
153        cpuAbilityContext2D.lineWidth = 1;
154        cpuAbilityContext2D.globalAlpha = 0.6;
155        let drawHeight: number = Math.floor(((cpuAbilityData.value || 0) * (cpuAbilityData.frame.height || 0) * 1.0) / maxCpuUtilization);
156        cpuAbilityContext2D.fillRect(
157          cpuAbilityData.frame.x,
158          cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4,
159          width,
160          drawHeight
161        );
162        cpuAbilityContext2D.beginPath();
163        cpuAbilityContext2D.arc(
164          cpuAbilityData.frame.x,
165          cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4,
166          3,
167          0,
168          2 * Math.PI,
169          true
170        );
171        cpuAbilityContext2D.fill();
172        cpuAbilityContext2D.globalAlpha = 1.0;
173        cpuAbilityContext2D.stroke();
174        cpuAbilityContext2D.beginPath();
175        cpuAbilityContext2D.moveTo(cpuAbilityData.frame.x + 3, cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4);
176        cpuAbilityContext2D.lineWidth = 3;
177        cpuAbilityContext2D.lineTo(cpuAbilityData.frame.x + width, cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4);
178        cpuAbilityContext2D.stroke();
179      } else {
180        cpuAbilityContext2D.globalAlpha = 0.6;
181        cpuAbilityContext2D.lineWidth = 1;
182        let drawHeight: number = Math.floor(((cpuAbilityData.value || 0) * (cpuAbilityData.frame.height || 0)) / maxCpuUtilization);
183        cpuAbilityContext2D.fillRect(
184          cpuAbilityData.frame.x,
185          cpuAbilityData.frame.y + cpuAbilityData.frame.height - drawHeight + 4,
186          width,
187          drawHeight
188        );
189      }
190    }
191    cpuAbilityContext2D.globalAlpha = 1.0;
192    cpuAbilityContext2D.lineWidth = 1;
193  }
194
195  static setCpuAbilityFrame(
196    cpuAbilityNode: any,
197    padding: number,
198    startNS: number,
199    endNS: number,
200    totalNS: number,
201    frame: any
202  ) {
203    let cpuAbilityStartPointX: number, cpuAbilityEndPointX: number;
204
205    if ((cpuAbilityNode.startNS || 0) < startNS) {
206      cpuAbilityStartPointX = 0;
207    } else {
208      cpuAbilityStartPointX = ns2x(cpuAbilityNode.startNS || 0, startNS, endNS, totalNS, frame);
209    }
210    if ((cpuAbilityNode.startNS || 0) + (cpuAbilityNode.dur || 0) > endNS) {
211      cpuAbilityEndPointX = frame.width;
212    } else {
213      cpuAbilityEndPointX = ns2x(
214        (cpuAbilityNode.startNS || 0) + (cpuAbilityNode.dur || 0),
215        startNS,
216        endNS,
217        totalNS,
218        frame
219      );
220    }
221    let frameWidth: number =
222      cpuAbilityEndPointX - cpuAbilityStartPointX <= 1 ? 1 : cpuAbilityEndPointX - cpuAbilityStartPointX;
223    if (!cpuAbilityNode.frame) {
224      cpuAbilityNode.frame = {};
225    }
226    cpuAbilityNode.frame.x = Math.floor(cpuAbilityStartPointX);
227    cpuAbilityNode.frame.y = frame.y + padding;
228    cpuAbilityNode.frame.width = Math.ceil(frameWidth);
229    cpuAbilityNode.frame.height = Math.floor(frame.height - padding * 2);
230  }
231}
232
233export class CpuAbility {
234  context: any;
235  params: any;
236}
237