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 {
17  dataFilterHandler,
18  isFrameContainPoint,
19  Rect,
20  Render,
21  RequestMessage,
22  drawString,
23  drawLoadingFrame,
24} from './ProcedureWorkerCommon';
25import { TraceRow } from '../../component/trace/base/TraceRow';
26import { Utils } from '../../component/trace/base/Utils';
27import { ThreadStruct as BaseThreadStruct } from '../../bean/ThreadStruct';
28import { SpSystemTrace } from '../../component/SpSystemTrace';
29import { SpSegmentationChart } from '../../component/chart/SpSegmentationChart';
30import { ns2x } from './ProcedureWorkerCommon';
31import { Flag } from '../../component/trace/timer-shaft/Flag';
32import { CpuFreqExtendStruct } from './ProcedureWorkerFreqExtend';
33import { BinderStruct } from './procedureWorkerBinder';
34import { TabPaneFreqStatesDataCut } from '../../component/trace/sheet/states/TabPaneFreqStatesDataCut';
35export class ThreadRender extends Render {
36  renderMainThread(
37    threadReq: {
38      context: CanvasRenderingContext2D;
39      useCache: boolean;
40      type: string;
41      translateY: number;
42    },
43    row: TraceRow<ThreadStruct>
44  ): void {
45    let threadList = row.dataList;
46    let threadFilter = row.dataListCache;
47    dataFilterHandler(threadList, threadFilter, {
48      startKey: 'startTime',
49      durKey: 'dur',
50      startNS: TraceRow.range?.startNS ?? 0,
51      endNS: TraceRow.range?.endNS ?? 0,
52      totalNS: TraceRow.range?.totalNS ?? 0,
53      frame: row.frame,
54      paddingTop: 3,
55      useCache: threadReq.useCache || !(TraceRow.range?.refresh ?? false),
56    });
57    drawLoadingFrame(threadReq.context, threadFilter, row);
58    threadReq.context.beginPath();
59    let find: boolean = false;
60    for (let re of threadFilter) {
61      re.translateY = threadReq.translateY;
62      ThreadStruct.drawThread(threadReq.context, re);
63      if (row.isHover && re.frame && isFrameContainPoint(re.frame!, row.hoverX, row.hoverY)) {
64        ThreadStruct.hoverThreadStruct = re;
65        find = true;
66      }
67    }
68    threadReq.context.closePath();
69  }
70
71  render(threadReq: RequestMessage, threadList: Array<unknown>, threadFilter: Array<unknown>): void {}
72}
73
74export function ThreadStructOnClick(
75  clickRowType: string,
76  sp: SpSystemTrace,
77  threadClickHandler: unknown,
78  cpuClickHandler: unknown,
79  prioClickHandlerFunc: unknown,
80  entry?: ThreadStruct
81): Promise<unknown> {
82  return new Promise((resolve, reject) => {
83    if (clickRowType === TraceRow.ROW_TYPE_THREAD && (ThreadStruct.hoverThreadStruct || entry)) {
84      sp.removeLinkLinesByBusinessType('thread');
85      ThreadStruct.selectThreadStruct = entry || ThreadStruct.hoverThreadStruct;
86      sp.timerShaftEL?.drawTriangle(ThreadStruct.selectThreadStruct!.startTime || 0, 'inverted');
87      sp.traceSheetEL?.displayThreadData(ThreadStruct.selectThreadStruct!,
88        //@ts-ignore
89        threadClickHandler, cpuClickHandler, prioClickHandlerFunc);
90      sp.timerShaftEL?.modifyFlagList(undefined);
91      reject(new Error());
92    } else {
93      resolve(null);
94    }
95  });
96}
97export class ThreadStruct extends BaseThreadStruct {
98  static otherColor = '#673ab7';
99  static uninterruptibleSleepColor = '#f19d38';
100  static uninterruptibleSleepNonIOColor = '#795548';
101  static traceColor = '#0d47a1';
102  static sColor = '#FBFBFB';
103  static hoverThreadStruct: ThreadStruct | undefined;
104  static selectThreadStruct: ThreadStruct | undefined;
105  static selectThreadStructList: Array<ThreadStruct> = [];
106  static firstselectThreadStruct: ThreadStruct | undefined;
107  static isClickPrio: boolean = false;
108  static prioCount: Array<unknown> = [];
109  argSetID: number | undefined;
110  translateY: number | undefined;
111  textMetricsWidth: number | undefined;
112  static startCycleTime: number = 0;
113  static endTime: number = 0;
114
115  static drawThread(threadContext: CanvasRenderingContext2D, data: ThreadStruct): void {
116    if (data.frame) {
117
118      threadContext.globalAlpha = 1;
119      let stateText = ThreadStruct.getEndState(data.state || '');
120      threadContext.fillStyle = Utils.getStateColor(data.state || '');
121      if ('S' === data.state) {
122        threadContext.globalAlpha = 0.2;
123      };
124      threadContext.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height);
125      threadContext.fillStyle = '#fff';
126      threadContext.textBaseline = 'middle';
127      threadContext.font = '8px sans-serif';
128      data.frame.width > 7 && drawString(threadContext, stateText, 2, data.frame, data);
129      if (
130        ThreadStruct.selectThreadStruct &&
131        ThreadStruct.equals(ThreadStruct.selectThreadStruct, data) &&
132        data.state !== 'S'
133      ) {
134        threadContext.strokeStyle = '#232c5d';
135        threadContext.lineWidth = 2;
136        threadContext.strokeRect(
137          data.frame.x,
138          data.frame.y,
139          data.frame.width - 2,
140          data.frame.height
141        );
142      }
143      if (!ThreadStruct.selectThreadStruct) {
144        ThreadStruct.isClickPrio = false;
145      }
146    }
147  }
148}
149