• 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 { TraceRow } from '../../component/trace/base/TraceRow';
18import {
19  BaseStruct,
20  drawLoadingFrame,
21  drawString,
22  isFrameContainPoint,
23  ns2x,
24  Rect,
25  Render,
26} from './ProcedureWorkerCommon';
27import {SpSystemTrace} from "../../component/SpSystemTrace";
28
29export class FrameAnimationRender extends Render {
30  renderMainThread(
31    req: {
32      useCache: boolean;
33      context: CanvasRenderingContext2D;
34      type: string;
35    },
36    row: TraceRow<FrameAnimationStruct>
37  ): void {
38    let frameAnimationList: FrameAnimationStruct[] = row.dataList;
39    let frameAnimationFilter: FrameAnimationStruct[] = row.dataListCache;
40    this.frameAnimation(
41      frameAnimationList,
42      frameAnimationFilter,
43      TraceRow.range!.startNS,
44      TraceRow.range!.endNS,
45      TraceRow.range!.totalNS,
46      row.frame,
47      req.useCache || !TraceRow.range!.refresh
48    );
49    drawLoadingFrame(req.context, row.dataListCache, row);
50    req.context.beginPath();
51    let find: boolean = false;
52    for (let index: number = 0; index < frameAnimationFilter.length; index++) {
53      let currentAnimationStruct: FrameAnimationStruct = frameAnimationFilter[index];
54      FrameAnimationStruct.draw(req.context, currentAnimationStruct, row);
55      if (
56        row.isHover &&
57        currentAnimationStruct.frame &&
58        isFrameContainPoint(currentAnimationStruct.frame, row.hoverX, row.hoverY)
59      ) {
60        FrameAnimationStruct.hoverFrameAnimationStruct = currentAnimationStruct;
61        find = true;
62      }
63    }
64    if (!find && row.isHover) {
65      FrameAnimationStruct.hoverFrameAnimationStruct = undefined;
66    }
67    req.context.closePath();
68  }
69
70  private frameAnimation(
71    frameAnimationList: FrameAnimationStruct[],
72    frameAnimationFilter: FrameAnimationStruct[],
73    startNS: number = 0,
74    endNS: number = 0,
75    totalNS: number,
76    frame: Rect,
77    use: boolean
78  ): void {
79    if (use && frameAnimationFilter.length > 0) {
80      for (let index: number = 0; index < frameAnimationFilter.length; index++) {
81        let frameAnimationNode: FrameAnimationStruct = frameAnimationFilter[index];
82        frameAnimationNode.frame = undefined;
83        FrameAnimationStruct.setFrameAnimation(frameAnimationNode, padding, startNS, endNS, totalNS, frame);
84      }
85      return;
86    }
87    frameAnimationFilter.length = 0;
88    if (frameAnimationList) {
89      for (let index: number = 0; index < frameAnimationList.length; index++) {
90        let currentFrameAnimation: FrameAnimationStruct = frameAnimationList[index];
91        if (
92          (currentFrameAnimation.startTs || 0) + (currentFrameAnimation.dur || 0) > startNS &&
93          (currentFrameAnimation.startTs || 0) < endNS
94        ) {
95          FrameAnimationStruct.setFrameAnimation(
96            currentFrameAnimation,
97            padding,
98            startNS,
99            endNS || 0,
100            totalNS || 0,
101            frame
102          );
103          frameAnimationFilter.push(currentFrameAnimation);
104        }
105      }
106    }
107  }
108}
109export function FrameAnimationStructOnClick(clickRowType: string, sp: SpSystemTrace) {
110  return new Promise((resolve,reject) => {
111    if (clickRowType === TraceRow.ROW_TYPE_FRAME_ANIMATION && FrameAnimationStruct.hoverFrameAnimationStruct) {
112      FrameAnimationStruct.selectFrameAnimationStruct = FrameAnimationStruct.hoverFrameAnimationStruct;
113      sp.traceSheetEL?.displayFrameAnimationData(FrameAnimationStruct.selectFrameAnimationStruct);
114      sp.timerShaftEL?.modifyFlagList(undefined);
115      reject();
116    }else{
117      resolve(null);
118    }
119  });
120}
121export class FrameAnimationStruct extends BaseStruct {
122  static hoverFrameAnimationStruct: FrameAnimationStruct | undefined;
123  static selectFrameAnimationStruct: FrameAnimationStruct | undefined;
124  dur: number = 0;
125  status: string = '';
126  animationId: number | undefined;
127  fps: number | undefined;
128  depth: number = 0;
129  startTs: number = 0;
130  endTs: number = 0;
131  frameInfo: string | undefined;
132  name: string | undefined;
133
134  static setFrameAnimation(
135    animationNode: FrameAnimationStruct,
136    padding: number,
137    startNS: number,
138    endNS: number,
139    totalNS: number,
140    frame: Rect
141  ): void {
142    let stateStartPointX: number;
143    let stateEndPointX: number;
144    if ((animationNode.startTs || 0) < startNS) {
145      stateStartPointX = 0;
146    } else {
147      stateStartPointX = ns2x(animationNode.startTs || 0, startNS, endNS, totalNS, frame);
148    }
149    if ((animationNode.startTs || 0) + (animationNode.dur || 0) > endNS) {
150      stateEndPointX = frame.width;
151    } else {
152      stateEndPointX = ns2x((animationNode.startTs || 0) + (animationNode.dur || 0), startNS, endNS, totalNS, frame);
153    }
154    let frameWidth: number =
155      stateEndPointX - stateStartPointX <= unitIndex ? unitIndex : stateEndPointX - stateStartPointX;
156    if (!animationNode.frame) {
157      animationNode.frame = new Rect(0, 0, 0, 0);
158    }
159    animationNode.frame.x = Math.floor(stateStartPointX);
160    animationNode.frame.y = frame.y + animationNode.depth * 20 + padding;
161    animationNode.frame.width = Math.ceil(frameWidth);
162    animationNode.frame.height = 20 - multiple * padding;
163  }
164
165  static draw(
166    ctx: CanvasRenderingContext2D,
167    frameAnimationNode: FrameAnimationStruct,
168    row: TraceRow<FrameAnimationStruct>
169  ): void {
170    let tsFixed: number = 6;
171    let isHover: boolean = row.isHover;
172    let frame = frameAnimationNode.frame;
173    if (frame) {
174      let nsToMillisecond = 1000_000;
175      ctx.globalAlpha = 1.0;
176      ctx.lineWidth = 1;
177      ctx.lineJoin = 'round';
178      ctx.fillStyle = ColorUtils.ANIMATION_COLOR[6];
179      ctx.fillRect(frame.x, frame.y, frame.width, frame.height);
180      ctx.fillStyle = ColorUtils.ANIMATION_COLOR[3];
181      ctx.textBaseline = 'middle';
182      ctx.font = '8px sans-serif';
183      drawString(
184        ctx,
185        `${frameAnimationNode.status} (${(frameAnimationNode.dur / nsToMillisecond).toFixed(tsFixed)} ms)`,
186        textPadding,
187        frame,
188        frameAnimationNode
189      );
190      ctx.lineWidth = 2;
191      if (
192        (frameAnimationNode === FrameAnimationStruct.hoverFrameAnimationStruct && isHover) ||
193        frameAnimationNode === FrameAnimationStruct.selectFrameAnimationStruct
194      ) {
195        ctx.globalAlpha = 0.8;
196        ctx.strokeStyle = ColorUtils.ANIMATION_COLOR[3];
197
198        ctx.strokeRect(frame.x + padding, frame.y, frame.width - padding, frame.height);
199      } else {
200        ctx.strokeStyle = ColorUtils.ANIMATION_COLOR[2];
201        ctx.strokeRect(frame.x + padding, frame.y, frame.width - padding, frame.height);
202      }
203    }
204  }
205}
206
207const padding: number = 2;
208const multiple: number = 2;
209const unitIndex: number = 1;
210const textPadding: number = 5;
211