• 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  drawFlagLine,
20  drawLines,
21  drawLoading,
22  drawSelection,
23  drawWakeUp,
24  ns2x,
25  Render,
26  RequestMessage,
27} from './ProcedureWorkerCommon.js';
28import { CpuStruct } from './ProcedureWorkerCPU.js';
29import { TraceRow } from '../../component/trace/base/TraceRow.js';
30
31export class ProcessRender extends Render {
32  renderMainThread(req: any, row: TraceRow<ProcessStruct>) {
33    let list = row.dataList;
34    let filter = row.dataListCache;
35    proc(
36      list,
37      filter,
38      TraceRow.range!.startNS,
39      TraceRow.range!.endNS,
40      TraceRow.range!.totalNS,
41      row.frame,
42      req.useCache || !TraceRow.range!.refresh
43    );
44    req.context.beginPath();
45    let path = new Path2D();
46    let miniHeight: number = 0;
47    miniHeight = Math.round((row.frame.height - CpuStruct.cpuCount * 2) / CpuStruct.cpuCount);
48    req.context.fillStyle = ColorUtils.colorForTid(req.pid || 0);
49    for (let re of filter) {
50      ProcessStruct.draw(req.context, path, re, miniHeight);
51    }
52    req.context.fill(path);
53    req.context.closePath();
54  }
55
56  render(processReq: RequestMessage, list: Array<any>, filter: Array<any>) {
57    if (processReq.lazyRefresh) {
58      proc(
59        list,
60        filter,
61        processReq.startNS,
62        processReq.endNS,
63        processReq.totalNS,
64        processReq.frame,
65        processReq.useCache || !processReq.range.refresh
66      );
67    } else {
68      if (!processReq.useCache) {
69        proc(list, filter, processReq.startNS, processReq.endNS, processReq.totalNS, processReq.frame, false);
70      }
71    }
72    if (processReq.canvas) {
73      processReq.context.clearRect(0, 0, processReq.frame.width, processReq.frame.height);
74      let arr = filter;
75      if (arr.length > 0 && !processReq.range.refresh && !processReq.useCache && processReq.lazyRefresh) {
76        drawLoading(
77          processReq.context,
78          processReq.startNS,
79          processReq.endNS,
80          processReq.totalNS,
81          processReq.frame,
82          arr[0].startTime,
83          arr[arr.length - 1].startTime + arr[arr.length - 1].dur
84        );
85      }
86      processReq.context.beginPath();
87      CpuStruct.cpuCount = processReq.params.cpuCount;
88      drawLines(processReq.context, processReq.xs, processReq.frame.height, processReq.lineColor);
89      let path = new Path2D();
90      let miniHeight: number = 0;
91      miniHeight = Math.round((processReq.frame.height - CpuStruct.cpuCount * 2) / CpuStruct.cpuCount);
92      processReq.context.fillStyle = ColorUtils.colorForTid(processReq.params.pid || 0);
93      for (let re of filter) {
94        ProcessStruct.draw(processReq.context, path, re, miniHeight);
95      }
96      processReq.context.fill(path);
97      drawSelection(processReq.context, processReq.params);
98      processReq.context.closePath();
99      drawFlagLine(
100        processReq.context,
101        processReq.flagMoveInfo,
102        processReq.flagSelectedInfo,
103        processReq.startNS,
104        processReq.endNS,
105        processReq.totalNS,
106        processReq.frame,
107        processReq.slicesTime
108      );
109    }
110    // @ts-ignore
111    self.postMessage({
112      id: processReq.id,
113      type: processReq.type,
114      results: processReq.canvas ? undefined : filter,
115      hover: undefined,
116    });
117  }
118}
119export function proc(
120  processList: Array<any>,
121  res: Array<any>,
122  startNS: number,
123  endNS: number,
124  totalNS: number,
125  frame: any,
126  use: boolean
127) {
128  if (use && res.length > 0) {
129    res.forEach((it) => ProcessStruct.setProcessFrame(it, 5, startNS || 0, endNS || 0, totalNS || 0, frame));
130    return;
131  }
132  res.length = 0;
133  if (processList) {
134    for (let i = 0, len = processList.length; i < len; i++) {
135      let it = processList[i];
136      if ((it.startTime || 0) + (it.dur || 0) > (startNS || 0) && (it.startTime || 0) < (endNS || 0)) {
137        ProcessStruct.setProcessFrame(processList[i], 5, startNS || 0, endNS || 0, totalNS || 0, frame);
138        if (
139          i > 0 &&
140          (processList[i - 1].frame?.x || 0) == (processList[i].frame?.x || 0) &&
141          (processList[i - 1].frame?.width || 0) == (processList[i].frame?.width || 0)
142        ) {
143        } else {
144          res.push(processList[i]);
145        }
146      }
147    }
148  }
149}
150
151const padding = 1;
152
153export class ProcessStruct extends BaseStruct {
154  cpu: number | undefined;
155  dur: number | undefined;
156  id: number | undefined;
157  pid: number | undefined;
158  process: string | undefined;
159  startTime: number | undefined;
160  state: string | undefined;
161  thread: string | undefined;
162  tid: number | undefined;
163  ts: number | undefined;
164  type: string | undefined;
165  utid: number | undefined;
166
167  static draw(ctx: CanvasRenderingContext2D, path: Path2D, data: ProcessStruct, miniHeight: number) {
168    if (data.frame) {
169      path.rect(data.frame.x, data.frame.y + (data.cpu || 0) * miniHeight + padding, data.frame.width, miniHeight);
170    }
171  }
172
173  static setFrame(processNode: any, pns: number, startNS: number, endNS: number, frame: any) {
174    if ((processNode.startTime || 0) < startNS) {
175      processNode.frame.x = 0;
176    } else {
177      processNode.frame.x = Math.floor(((processNode.startTime || 0) - startNS) / pns);
178    }
179    if ((processNode.startTime || 0) + (processNode.dur || 0) > endNS) {
180      processNode.frame.width = frame.width - processNode.frame.x;
181    } else {
182      processNode.frame.width = Math.ceil(
183        ((processNode.startTime || 0) + (processNode.dur || 0) - startNS) / pns - processNode.frame.x
184      );
185    }
186    if (processNode.frame.width < 1) {
187      processNode.frame.width = 1;
188    }
189  }
190
191  static setProcessFrame(
192    processNode: any,
193    padding: number,
194    startNS: number,
195    endNS: number,
196    totalNS: number,
197    frame: any
198  ) {
199    let x1: number;
200    let x2: number;
201    if ((processNode.startTime || 0) < startNS) {
202      x1 = 0;
203    } else {
204      x1 = ns2x(processNode.startTime || 0, startNS, endNS, totalNS, frame);
205    }
206    if ((processNode.startTime || 0) + (processNode.dur || 0) > endNS) {
207      x2 = frame.width;
208    } else {
209      x2 = ns2x((processNode.startTime || 0) + (processNode.dur || 0), startNS, endNS, totalNS, frame);
210    }
211    let processGetV: number = x2 - x1 <= 1 ? 1 : x2 - x1;
212    if (!processNode.frame) {
213      processNode.frame = {};
214    }
215    processNode.frame.x = Math.floor(x1);
216    processNode.frame.y = Math.floor(frame.y + 2);
217    processNode.frame.width = Math.ceil(processGetV);
218    processNode.frame.height = Math.floor(frame.height - padding * 2);
219  }
220}
221