1/*
2 * Copyright (C) 2024 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, drawString, Rect } from './ProcedureWorkerCommon';
17import { TraceRow } from '../../component/trace/base/TraceRow';
18import { ColorUtils } from '../../component/trace/base/ColorUtils';
19import { SpSystemTrace } from '../../component/SpSystemTrace';
20
21export class DmaFenceRender {
22  renderMainThread(
23    req: {
24      dmaFenceContext: CanvasRenderingContext2D;
25      useCache: boolean;
26      type: string;
27      maxValue: number;
28      index: number;
29      maxName: string;
30    },
31    DmaFenceRow: TraceRow<DmaFenceStruct>
32  ): void {
33    let list = DmaFenceRow.dataList;
34    let filter = DmaFenceRow.dataListCache;
35    dataFilterHandler(list, filter, {
36      startKey: 'startTime',
37      durKey: 'dur',
38      startNS: TraceRow.range?.startNS ?? 0,
39      endNS: TraceRow.range?.endNS ?? 0,
40      totalNS: TraceRow.range?.totalNS ?? 0,
41      frame: DmaFenceRow.frame,
42      paddingTop: 8,
43      useCache: req.useCache || !(TraceRow.range?.refresh ?? false),
44    });
45    let find = false;
46    let offset = 3;
47    drawLoadingFrame(req.dmaFenceContext, filter, DmaFenceRow);
48    for (let re of filter) {
49      let depth = re.dur === 0 ? 1 : 0;
50      if (DmaFenceRow.isHover) {
51        if (
52          re.frame &&
53          DmaFenceRow.hoverX >= re.frame.x - offset &&
54          DmaFenceRow.hoverX <= re.frame.x + re.frame.width + offset &&
55          DmaFenceRow.hoverY <= (depth + 1) * 24 + 8 &&
56          DmaFenceRow.hoverY >= depth * 24 + 8
57        ) {
58          re.frame!.height = 24;
59          re.frame!.y = re.dur === 0 ? 32 : 8;
60          DmaFenceStruct.hoverDmaFenceStruct = re;
61          find = true;
62        }
63      }
64      req.dmaFenceContext.beginPath();
65      req.dmaFenceContext.globalAlpha = 0.6;
66      DmaFenceStruct.draw(req.dmaFenceContext, re, DmaFenceRow);
67      if (!find && DmaFenceRow.isHover) {
68        DmaFenceStruct.hoverDmaFenceStruct = undefined;
69      }
70      req.dmaFenceContext.closePath();
71    }
72  }
73}
74
75export function DmaFenceStructOnClick(
76  rowType: string,
77  sp: SpSystemTrace,
78  entry?: DmaFenceStruct,
79): Promise<unknown> {
80  return new Promise((resolve, reject) => {
81    if (rowType === TraceRow.ROW_TYPE_DMA_FENCE && (DmaFenceStruct.hoverDmaFenceStruct || entry)) {
82      DmaFenceStruct.selectDmaFenceStruct = entry || DmaFenceStruct.hoverDmaFenceStruct;
83      sp.traceSheetEL?.displayDmaFenceData(DmaFenceStruct.selectDmaFenceStruct!, sp.currentRow!.dataListCache);
84      sp.timerShaftEL?.modifyFlagList(undefined);
85      reject(new Error());
86    } else {
87      resolve(null);
88    }
89  });
90}
91
92export class DmaFenceStruct extends BaseStruct {
93  static hoverDmaFenceStruct: DmaFenceStruct | undefined;
94  static selectDmaFenceStruct: DmaFenceStruct | undefined;
95  static maxVal: number | undefined = 0;
96  static index = 0;
97  static maxDepth: number = 0;
98  value: number | undefined = 20;
99  startTime: number | undefined;
100  dur: number | undefined;
101  id: number = 0;
102  cat: string = '';
103  seqno: string = '';
104  sliceName: string = '';
105  driver: string = '';
106  context: string = '';
107  depth: number = 0;
108
109  static draw(ctx: CanvasRenderingContext2D, data: DmaFenceStruct, row: TraceRow<DmaFenceStruct>): void {
110    if (data.frame) {
111      if (data.dur === 0) {
112        data.depth = 1;
113      }
114      if (data.depth > DmaFenceStruct.maxDepth) {
115        DmaFenceStruct.maxDepth = data.depth;
116        row.style.height = `${(DmaFenceStruct.maxDepth + 1) * 24 + 16}px`;
117      }
118      let colorIndex = Number(data.startTime?.toString().substring(-1));
119      let color = ColorUtils.colorForTid(colorIndex);
120      ctx.fillStyle = color;
121      if (data === DmaFenceStruct.hoverDmaFenceStruct || data === DmaFenceStruct.selectDmaFenceStruct) {
122        ctx.globalAlpha = 1.0;
123        ctx.lineWidth = 1;
124        ctx.strokeStyle = '#a56df5';
125        ctx.fillRect(data.frame.x, data.depth * 24 + 8, data.frame.width < 1 ? 1 : data.frame.width, 24);
126      } else {
127        ctx.globalAlpha = 0.6;
128        ctx.fillRect(data.frame.x, data.depth * 24 + 8, data.frame.width < 1 ? 1 : data.frame.width, 24);
129      }
130      //描边
131      if (data.id === DmaFenceStruct.selectDmaFenceStruct?.id &&
132        data.startTime === DmaFenceStruct.selectDmaFenceStruct?.startTime &&
133        data.depth === DmaFenceStruct.selectDmaFenceStruct?.depth) {
134        ctx.strokeStyle = '#000';
135        ctx.lineWidth = 1;
136        let positionY = data.depth * 24 + 8;
137        ctx.strokeRect(data.frame.x, positionY + 1, data.frame.width - 2, 22);
138      }
139      if (data.frame!.width > 8) {
140        ctx.lineWidth = 1;
141        ctx.fillStyle = ColorUtils.funcTextColor(
142          ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.startTime!.toString() || '', 0, ColorUtils.FUNC_COLOR.length)]
143        );
144        ctx.textBaseline = 'middle';
145        drawString(
146          ctx,
147          `${data.sliceName || ''}`,
148          6,
149          new Rect(data.frame!.x, data.depth * 24 + 8, data.frame!.width, 24),
150          data
151        );
152      }
153    }
154  }
155}
156