• 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 { BaseStruct, dataFilterHandler, drawLoadingFrame, isFrameContainPoint, Render } from './ProcedureWorkerCommon';
17import { TraceRow } from '../../component/trace/base/TraceRow';
18import { ColorUtils } from '../../component/trace/base/ColorUtils';
19
20export class XpowerThreadCountRender extends Render {
21  renderMainThread(
22    xpowerReq: {
23      context: CanvasRenderingContext2D;
24      useCache: boolean;
25    },
26    row: TraceRow<XpowerThreadCountStruct>
27  ): void {
28    let xpowerThreadCountList = row.dataList;
29    let xpowerThreadCountFilter = row.dataListCache;
30    let maxValue = 0;
31    if (xpowerThreadCountFilter.length > 0) {// @ts-ignore
32      maxValue = xpowerThreadCountFilter.map((item) => item.value).reduce((a: unknown, b: unknown) => Math.max(a, b));
33    }
34    dataFilterHandler(xpowerThreadCountList, xpowerThreadCountFilter, {
35      startKey: 'startNS',
36      durKey: 'dur',
37      startNS: TraceRow.range?.startNS ?? 0,
38      endNS: TraceRow.range?.endNS ?? 0,
39      totalNS: TraceRow.range?.totalNS ?? 0,
40      frame: row.frame,
41      paddingTop: 5,
42      useCache: xpowerReq.useCache || !(TraceRow.range?.refresh ?? false),
43    });
44    drawLoadingFrame(xpowerReq.context, xpowerThreadCountFilter, row);
45    xpowerReq.context.beginPath();
46    let find = false;
47    for (let re of xpowerThreadCountFilter) {
48      XpowerThreadCountStruct.draw(xpowerReq.context, re, maxValue);
49      if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) {
50        XpowerThreadCountStruct.hoverXpowerStruct = re;
51        find = true;
52      }
53    }
54    if (!find) {
55      XpowerThreadCountStruct.hoverXpowerStruct = undefined;
56    }
57    xpowerReq.context.closePath();
58    let maxValueStr = String(maxValue);
59    let textMetrics = xpowerReq.context.measureText(maxValueStr);
60    xpowerReq.context.globalAlpha = 0.8;
61    xpowerReq.context.fillStyle = '#f0f0f0';
62    xpowerReq.context.fillRect(0, 5, textMetrics.width + 8, 18);
63    xpowerReq.context.globalAlpha = 1;
64    xpowerReq.context.fillStyle = '#333';
65    xpowerReq.context.textBaseline = 'middle';
66    xpowerReq.context.fillText(maxValueStr, 4, 5 + 9);
67  }
68}
69
70export class XpowerThreadCountStruct extends BaseStruct {
71  static maxValue: number = 0;
72  static hoverXpowerStruct: XpowerThreadCountStruct | undefined;
73  static selectXpowerStruct: XpowerThreadCountStruct | undefined;
74  static index = 0;
75  value: number = 0;
76  startNS: number = 0;
77  dur: number = 0; //自补充,数据库没有返回
78
79  static draw(xpowerContext: CanvasRenderingContext2D, data: XpowerThreadCountStruct, maxValue: number): void {
80    if (data.frame) {
81      const width = data.frame.width || 0;
82      const drawHeight = this.calculateDrawHeight(data, maxValue);
83      const cutHeight = 0;
84
85      if (XpowerThreadCountStruct.isHover(data)) {
86        this.drawHoverState(xpowerContext, data, width, drawHeight, cutHeight);
87      } else {
88        this.drawNormalState(xpowerContext, data, width, drawHeight, cutHeight);
89      }
90    }
91    xpowerContext.globalAlpha = 1.0;
92    xpowerContext.lineWidth = 1;
93  }
94
95  private static calculateDrawHeight(data: XpowerThreadCountStruct, maxValue: number): number {
96    let drawHeight = Math.floor(((data.value || 0) * (data.frame!.height || 0) * 1.0) / maxValue);
97    return drawHeight === 0 ? 1 : drawHeight;
98  }
99
100  private static drawHoverState(
101    xpowerContext: CanvasRenderingContext2D,
102    data: XpowerThreadCountStruct,
103    width: number,
104    drawHeight: number,
105    cutHeight: number
106  ): void {
107    xpowerContext.fillStyle = ColorUtils.colorForTid(XpowerThreadCountStruct.index);
108    xpowerContext.strokeStyle = ColorUtils.colorForTid(XpowerThreadCountStruct.index);
109    xpowerContext.lineWidth = 1;
110    xpowerContext.globalAlpha = 0.6;
111    xpowerContext.fillRect(
112      data.frame!.x,
113      data.frame!.y + data.frame!.height - drawHeight - cutHeight,
114      width,
115      drawHeight
116    );
117    xpowerContext.beginPath();
118    xpowerContext.arc(
119      data.frame!.x,
120      data.frame!.y + data.frame!.height - drawHeight - cutHeight,
121      3,
122      0,
123      2 * Math.PI,
124      true
125    );
126    xpowerContext.fill();
127    xpowerContext.globalAlpha = 1.0;
128    xpowerContext.stroke();
129    xpowerContext.beginPath();
130    xpowerContext.moveTo(data.frame!.x + 3, data.frame!.y + data.frame!.height - drawHeight - cutHeight);
131    xpowerContext.lineWidth = 3;
132    xpowerContext.lineTo(data.frame!.x + width, data.frame!.y + data.frame!.height - drawHeight - cutHeight);
133    xpowerContext.stroke();
134  }
135
136  private static drawNormalState(
137    xpowerContext: CanvasRenderingContext2D,
138    data: XpowerThreadCountStruct,
139    width: number,
140    drawHeight: number,
141    cutHeight: number
142  ): void {
143    xpowerContext.fillStyle = ColorUtils.colorForTid(XpowerThreadCountStruct.index);
144    xpowerContext.strokeStyle = ColorUtils.colorForTid(XpowerThreadCountStruct.index);
145    xpowerContext.lineWidth = 1;
146    xpowerContext.globalAlpha = 1.0;
147    xpowerContext.strokeRect(
148      data.frame!.x,
149      data.frame!.y + data.frame!.height - drawHeight - cutHeight,
150      width,
151      drawHeight
152    );
153    xpowerContext.globalAlpha = 0.6;
154    xpowerContext.fillRect(
155      data.frame!.x,
156      data.frame!.y + data.frame!.height - drawHeight - cutHeight,
157      width,
158      drawHeight
159    );
160  }
161
162  static isHover(xpower: XpowerThreadCountStruct): boolean {
163    return (
164      xpower === XpowerThreadCountStruct.hoverXpowerStruct || xpower === XpowerThreadCountStruct.selectXpowerStruct
165    );
166  }
167}
168