• 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';
17import {
18  BaseStruct,
19  drawFlagLine,
20  drawLines,
21  drawLoading,
22  drawLoadingFrame,
23  drawSelection,
24  drawWakeUp,
25  ns2x,
26  Render,
27  RequestMessage,
28} from './ProcedureWorkerCommon';
29import { CpuStruct } from './cpu/ProcedureWorkerCPU';
30import { TraceRow } from '../../component/trace/base/TraceRow';
31
32export class ProcessRender extends Render {
33  renderMainThread(req: any, row: TraceRow<ProcessStruct>) {
34    let list = row.dataList;
35    let filter = row.dataListCache;
36    proc(
37      list,
38      filter,
39      TraceRow.range!.startNS || 0,
40      TraceRow.range!.endNS || 0,
41      TraceRow.range!.totalNS || 0,
42      row.frame,
43      req.useCache || !TraceRow.range!.refresh
44    );
45    drawLoadingFrame(req.context, filter, row, true);
46    req.context.beginPath();
47    let path = new Path2D();
48    let miniHeight: number = 0;
49    miniHeight = Math.round((row.frame.height - CpuStruct.cpuCount * 2) / CpuStruct.cpuCount);
50    req.context.fillStyle = ColorUtils.colorForTid(req.pid || 0);
51    for (let re of filter) {
52      ProcessStruct.draw(req.context, path, re, miniHeight);
53    }
54    req.context.fill(path);
55    req.context.closePath();
56  }
57}
58export function proc(
59  processList: Array<any>,
60  res: Array<any>,
61  startNS: number,
62  endNS: number,
63  totalNS: number,
64  frame: any,
65  use: boolean
66) {
67  if (use && res.length > 0) {
68    res.forEach((it) => ProcessStruct.setProcessFrame(it, 5, startNS, endNS, totalNS, frame));
69    return;
70  }
71  res.length = 0;
72  if (processList) {
73    for (let i = 0, len = processList.length; i < len; i++) {
74      let it = processList[i];
75      if ((it.startTime || 0) + (it.dur || 0) > startNS && (it.startTime || 0) < endNS) {
76        ProcessStruct.setProcessFrame(processList[i], 5, startNS, endNS, totalNS, frame);
77        if (
78          !(
79            i > 0 &&
80            (processList[i - 1].frame.x || 0) == (processList[i].frame.x || 0) &&
81            (processList[i - 1].frame.width || 0) == (processList[i].frame.width || 0)
82          )
83        ) {
84          res.push(processList[i]);
85        }
86      }
87    }
88  }
89}
90
91const padding = 1;
92
93export class ProcessStruct extends BaseStruct {
94  cpu: number | undefined;
95  dur: number | undefined;
96  id: number | undefined;
97  pid: number | undefined;
98  process: string | undefined;
99  startTime: number | undefined;
100  state: string | undefined;
101  thread: string | undefined;
102  tid: number | undefined;
103  ts: number | undefined;
104  type: string | undefined;
105  utid: number | undefined;
106
107  static draw(ctx: CanvasRenderingContext2D, path: Path2D, data: ProcessStruct, miniHeight: number) {
108    if (data.frame) {
109      path.rect(data.frame.x, data.frame.y + (data.cpu || 0) * miniHeight + padding, data.frame.width, miniHeight);
110    }
111  }
112
113  static setFrame(processNode: any, pns: number, startNS: number, endNS: number, frame: any) {
114    if ((processNode.startTime || 0) < startNS) {
115      processNode.frame.x = 0;
116    } else {
117      processNode.frame.x = Math.floor(((processNode.startTime || 0) - startNS) / pns);
118    }
119    if ((processNode.startTime || 0) + (processNode.dur || 0) > endNS) {
120      processNode.frame.width = frame.width - processNode.frame.x;
121    } else {
122      processNode.frame.width = Math.ceil(
123        ((processNode.startTime || 0) + (processNode.dur || 0) - startNS) / pns - processNode.frame.x
124      );
125    }
126    if (processNode.frame.width < 1) {
127      processNode.frame.width = 1;
128    }
129  }
130
131  static setProcessFrame(
132    processNode: any,
133    padding: number,
134    startNS: number,
135    endNS: number,
136    totalNS: number,
137    frame: any
138  ) {
139    let x1: number;
140    let x2: number;
141    if ((processNode.startTime || 0) < startNS) {
142      x1 = 0;
143    } else {
144      x1 = ns2x(processNode.startTime || 0, startNS, endNS, totalNS, frame);
145    }
146    if ((processNode.startTime || 0) + (processNode.dur || 0) > endNS) {
147      x2 = frame.width;
148    } else {
149      x2 = ns2x((processNode.startTime || 0) + (processNode.dur || 0), startNS, endNS, totalNS, frame);
150    }
151    let processGetV: number = x2 - x1 <= 1 ? 1 : x2 - x1;
152    if (!processNode.frame) {
153      processNode.frame = {};
154    }
155    processNode.frame.x = Math.floor(x1);
156    processNode.frame.y = Math.floor(frame.y + 2);
157    processNode.frame.width = Math.ceil(processGetV);
158    processNode.frame.height = Math.floor(frame.height - padding * 2);
159  }
160}
161