• 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 { TraceRow } from '../../component/trace/base/TraceRow.js';
18import {
19  BaseStruct,
20  isFrameContainPoint,
21  ns2x,
22  Render,
23  RequestMessage,
24  drawString,
25} from './ProcedureWorkerCommon.js';
26
27export class SoRender extends Render {
28  renderMainThread(
29    req: {
30      useCache: boolean;
31      context: CanvasRenderingContext2D;
32      type: string;
33    },
34    row: TraceRow<SoStruct>
35  ): void {
36    let soList = row.dataList;
37    let soFilter = row.dataListCache;
38    soDataFilter(
39      soList,
40      soFilter,
41      TraceRow.range!.startNS,
42      TraceRow.range!.endNS,
43      TraceRow.range!.totalNS,
44      row.frame,
45      req.useCache || !TraceRow.range!.refresh
46    );
47    req.context.beginPath();
48    let soFind = false;
49    for (let so of soFilter) {
50      SoStruct.draw(req.context, so);
51      if (row.isHover) {
52        if (so.dur === 0 || so.dur === null || so.dur === undefined) {
53          if (
54            so.frame &&
55            row.hoverX >= so.frame.x - 5 &&
56            row.hoverX <= so.frame.x + 5 &&
57            row.hoverY >= so.frame.y &&
58            row.hoverY <= so.frame.y + so.frame.height
59          ) {
60            SoStruct.hoverSoStruct = so;
61            soFind = true;
62          }
63        } else {
64          if (so.frame && isFrameContainPoint(so.frame, row.hoverX, row.hoverY)) {
65            SoStruct.hoverSoStruct = so;
66            soFind = true;
67          }
68        }
69      }
70    }
71    if (!soFind && row.isHover) SoStruct.hoverSoStruct = undefined;
72    req.context.closePath();
73  }
74
75  render(req: RequestMessage, list: Array<any>, filter: Array<any>): void {}
76}
77
78export function soDataFilter(
79  soList: Array<SoStruct>,
80  soFilter: Array<SoStruct>,
81  startNS: number,
82  endNS: number,
83  totalNS: number,
84  frame: any,
85  use: boolean
86): void {
87  if (use && soFilter.length > 0) {
88    for (let i = 0, len = soFilter.length ; i < len ; i++) {
89      if ((soFilter[i].startTs || 0) + (soFilter[i].dur || 0) >= startNS && (soFilter[i].startTs || 0) <= endNS) {
90        SoStruct.setSoFrame(soFilter[i], 0, startNS, endNS, totalNS, frame);
91      } else {
92        soFilter[i].frame = undefined;
93      }
94    }
95    return;
96  }
97  soFilter.length = 0;
98  if (soList) {
99    let groups = soList
100      .filter((it) => (it.startTs ?? 0) + (it.dur ?? 0) >= startNS && (it.startTs ?? 0) <= endNS)
101      .map((it) => {
102        SoStruct.setSoFrame(it, 0, startNS, endNS, totalNS, frame);
103        return it;
104      })
105      .reduce((pre: any, current, index, arr) => {
106        if (current.frame) {
107          (pre[`${ current.frame.x }-${ current.depth }`] = pre[`${ current.frame.x }-${ current.depth }`] || []).push(current);
108        }
109        return pre;
110      }, {});
111    Reflect.ownKeys(groups).map((kv) => {
112      let arr = groups[kv].sort((a: any, b: any) => b.dur - a.dur);
113      soFilter.push(arr[0]);
114    });
115  }
116}
117
118export class SoStruct extends BaseStruct {
119  static hoverSoStruct: SoStruct | undefined;
120  static selectSoStruct: SoStruct | undefined;
121  textMetricsWidth: number | undefined;
122  depth: number | undefined;
123  dur: number | undefined;
124  soName: string | undefined;
125  process: string | undefined;
126  startTs: number | undefined;
127  tid: number | undefined;
128  pid: number | undefined;
129  itid: number | undefined;
130
131  static setSoFrame(soNode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any): void {
132    let x1: number;
133    let x2: number;
134    if ((soNode.startTs || 0) > startNS && (soNode.startTs || 0) < endNS) {
135      x1 = ns2x(soNode.startTs || 0, startNS, endNS, totalNS, frame);
136    } else {
137      x1 = 0;
138    }
139    if (
140      (soNode.startTs || 0) + (soNode.dur || 0) > startNS &&
141      (soNode.startTs || 0) + (soNode.dur || 0) < endNS
142    ) {
143      x2 = ns2x((soNode.startTs || 0) + (soNode.dur || 0), startNS, endNS, totalNS, frame);
144    } else {
145      x2 = frame.width;
146    }
147    if (!soNode.frame) {
148      soNode.frame = {};
149    }
150    let getV: number = x2 - x1 < 1 ? 1 : x2 - x1;
151    soNode.frame.x = Math.floor(x1);
152    soNode.frame.y = soNode.depth * 20;
153    soNode.frame.width = Math.ceil(getV);
154    soNode.frame.height = 20;
155  }
156
157  static draw(ctx: CanvasRenderingContext2D, data: SoStruct): void {
158    if (data.frame) {
159      if (data.dur === undefined || data.dur === null) {
160      } else {
161
162        ctx.globalAlpha = 1;
163        ctx.fillStyle = ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.soName || '', 0, ColorUtils.FUNC_COLOR.length)];
164        let textColor = ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.soName || '', 0, ColorUtils.FUNC_COLOR.length)];
165        let miniHeight = 20;
166        if (SoStruct.hoverSoStruct && data.soName === SoStruct.hoverSoStruct.soName) {
167          ctx.globalAlpha = 0.7;
168        }
169        ctx.fillRect(data.frame.x, data.frame.y, data.frame.width, miniHeight - padding * 2);
170        if (data.frame.width > 10) {
171          ctx.strokeStyle = '#fff';
172          ctx.lineWidth = 1;
173          ctx.strokeRect(data.frame.x, data.frame.y, data.frame.width, miniHeight - padding * 2);
174          ctx.fillStyle = ColorUtils.funcTextColor(textColor);
175          drawString(ctx, `${ data.soName || '' }`, 5, data.frame, data);
176        }
177        if (data === SoStruct.selectSoStruct) {
178          ctx.strokeStyle = '#000';
179          ctx.lineWidth = 2;
180          ctx.strokeRect(data.frame.x, data.frame.y + 1, data.frame.width, miniHeight - padding * 2 - 2);
181        }
182      }
183    }
184  }
185
186}
187
188const padding = 1;
189