• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2021 Huawei Device Co., Ltd.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6//     http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14import { TraficEnum } from './utils/QueryEnum';
15import { JanksStruct } from '../../bean/JanksStruct';
16import { processFrameList } from './utils/AllMemoryCache';
17import { Args } from './CommonArgs';
18
19export const frameJankDataSql = (args: Args, configure: unknown): string => {
20  let timeLimit: string = '';
21  let flag: string = '';
22  let fsType: number = -1;
23  let fsFlag: string = '';
24  //@ts-ignore
25  const endNS = args.endNS;
26  //@ts-ignore
27  const startNS = args.startNS;
28  //@ts-ignore
29  const recordStartNS = args.recordStartNS;
30  switch (configure) {
31    case 'ExepectMemory':
32      fsType = 1;
33      flag = 'fs.flag as jankTag,';
34      break;
35    case 'ExpectedData':
36      fsType = 1;
37      flag = 'fs.flag as jankTag,';
38      timeLimit = `
39       AND (fs.ts - ${recordStartNS} + fs.dur) >= ${Math.floor(startNS)}
40       AND (fs.ts - ${recordStartNS}) <= ${Math.floor(endNS)}`;
41      break;
42    case 'ActualMemoryData':
43      fsType = 0;
44      flag =
45        '(case when (sf.flag == 1 or fs.flag == 1 ) then 1 when (sf.flag == 3 or fs.flag == 3 ) then 3 else 0 end) as jankTag,';
46      fsFlag = 'AND fs.flag <> 2';
47      break;
48    case 'ActualData':
49      fsType = 0;
50      flag =
51        '(case when (sf.flag == 1 or fs.flag == 1 ) then 1 when (sf.flag == 3 or fs.flag == 3 ) then 3 else 0 end) as jankTag,';
52      fsFlag = 'AND fs.flag <> 2';
53      timeLimit = `AND (fs.ts - ${recordStartNS} + fs.dur) >= ${Math.floor(startNS)}
54       AND (fs.ts - ${recordStartNS}) <= ${Math.floor(endNS)}`;
55      break;
56    default:
57      break;
58  }
59  let sql = setFrameJanksSql(args, timeLimit, flag, fsType, fsFlag);
60  return sql;
61};
62function setFrameJanksSql(args: Args, timeLimit: string, flag: string, fsType: number, fsFlag: string): string {
63  //@ts-ignore
64  const recordStartNS = args.recordStartNS;
65  return `SELECT sf.id,
66            'frameTime' as frameType,
67            fs.ipid,
68            fs.vsync as name,
69            fs.dur as appDur,
70            (sf.ts + sf.dur - fs.ts) as dur,
71            (fs.ts - ${recordStartNS}) AS ts,
72            fs.type,
73            ${flag}
74            pro.pid,
75            pro.name as cmdline,
76            (sf.ts - ${recordStartNS}) AS rsTs,
77            sf.vsync AS rsVsync,
78            sf.dur AS rsDur,
79            sf.ipid AS rsIpid,
80            proc.pid AS rsPid,
81            proc.name AS rsName
82        FROM frame_slice AS fs
83        LEFT JOIN process AS pro ON pro.id = fs.ipid
84        LEFT JOIN frame_slice AS sf ON fs.dst = sf.id
85        LEFT JOIN process AS proc ON proc.id = sf.ipid
86        WHERE fs.dst IS NOT NULL
87        AND fs.type = ${fsType}
88        ${fsFlag} ${timeLimit}
89        UNION
90        SELECT -1 as id,
91            'frameTime' as frameType,
92            fs.ipid,
93            fs.vsync  as name,
94            fs.dur as appDur,
95            fs.dur,
96            (fs.ts - ${recordStartNS}) AS ts,
97            fs.type,
98            fs.flag as jankTag,
99            pro.pid,
100            pro.name as cmdline,
101            NULL AS rsTs, NULL AS rsVsync, NULL AS rsDur, NULL AS rsIpid, NULL AS rsPid, NULL AS rsName
102        FROM frame_slice AS fs LEFT JOIN process AS pro ON pro.id = fs.ipid
103        WHERE fs.dst IS NULL
104        AND pro.name NOT LIKE '%render_service%'
105        AND fs.type = 1
106        ${fsFlag} ${timeLimit}
107        ORDER by ts`;
108}
109
110export function frameExpectedReceiver(data: unknown, proc: Function): void {
111  // @ts-ignore
112  if (data.params.trafic === TraficEnum.Memory) {
113    if (!processFrameList.has('FrameTimeLine_expected')) {
114      // @ts-ignore
115      let sql = frameJankDataSql(data.params, 'ExepectMemory');
116      processFrameList.set('FrameTimeLine_expected', proc(sql));
117    }
118    frameJanksReceiver(data, processFrameList.get('FrameTimeLine_expected')!, 'expected', true);
119  } else {
120    // @ts-ignore
121    let sql = frameJankDataSql(data.params, 'ExpectedData');
122    let res = proc(sql);
123    // @ts-ignore
124    frameJanksReceiver(data, res, 'expect', data.params.trafic !== TraficEnum.SharedArrayBuffer);
125  }
126}
127
128export function frameActualReceiver(data: unknown, proc: Function): void {
129  // @ts-ignore
130  if (data.params.trafic === TraficEnum.Memory) {
131    if (!processFrameList.has('FrameTimeLine_actual')) {
132      // @ts-ignore
133      let sql = frameJankDataSql(data.params, 'ActualMemoryData');
134      processFrameList.set('FrameTimeLine_actual', proc(sql));
135    }
136    frameJanksReceiver(data, processFrameList.get('FrameTimeLine_actual')!, 'actual', true);
137  } else {
138    // @ts-ignore
139    let sql = frameJankDataSql(data.params, 'ActualData');
140    let res = proc(sql);
141    // @ts-ignore
142    frameJanksReceiver(data, res, 'actual', data.params.trafic !== TraficEnum.SharedArrayBuffer);
143  }
144}
145let isIntersect = (leftData: JanksStruct, rightData: JanksStruct): boolean =>
146  Math.max(leftData.ts! + leftData.dur!, rightData.ts! + rightData.dur!) - Math.min(leftData.ts!, rightData.ts!) <
147  leftData.dur! + rightData.dur!;
148function frameJanksReceiver(data: unknown, res: unknown[], type: string, transfer: boolean): void {
149  let frameJanks = new FrameJanks(data, transfer, res.length);
150  let unitIndex: number = 1;
151  let depths: unknown[] = [];
152  for (let index = 0; index < res.length; index++) {
153    let item = res[index];
154    // @ts-ignore
155    data.params.trafic === TraficEnum.ProtoBuffer && (item = item.frameData);
156    // @ts-ignore
157    if (!item.dur || item.dur < 0) {
158      continue;
159    }
160    if (depths.length === 0) {
161      // @ts-ignore
162      item.depth = 0;
163      depths[0] = item;
164    } else {
165      let depthIndex: number = 0;
166      let isContinue: boolean = true;
167      while (isContinue) {
168        // @ts-ignore
169        if (isIntersect(depths[depthIndex], item)) {
170          if (depths[depthIndex + unitIndex] === undefined || !depths[depthIndex + unitIndex]) {
171            // @ts-ignore
172            item.depth = depthIndex + unitIndex;
173            depths[depthIndex + unitIndex] = item;
174            isContinue = false;
175          }
176        } else {
177          // @ts-ignore
178          item.depth = depthIndex;
179          depths[depthIndex] = item;
180          isContinue = false;
181        }
182        depthIndex++;
183      }
184    }
185    setFrameJanks(frameJanks, item, index);
186  }
187  postFrameJanksMessage(data, transfer, frameJanks, res.length);
188}
189function setFrameJanks(frameJanks: FrameJanks, itemData: unknown, index: number): void {
190  // @ts-ignore
191  frameJanks.id[index] = itemData.id;
192  // @ts-ignore
193  frameJanks.ipId[index] = itemData.ipid;
194  // @ts-ignore
195  frameJanks.name[index] = itemData.name;
196  // @ts-ignore
197  frameJanks.appDur[index] = itemData.appDur;
198  // @ts-ignore
199  frameJanks.dur[index] = itemData.dur;
200  // @ts-ignore
201  frameJanks.ts[index] = itemData.ts;
202  // @ts-ignore
203  frameJanks.jankTag[index] = itemData.jankTag ? itemData.jankTag : 0;
204  // @ts-ignore
205  frameJanks.pid[index] = itemData.pid;
206  // @ts-ignore
207  frameJanks.rsTs[index] = itemData.rsTs;
208  // @ts-ignore
209  frameJanks.rsVsync[index] = itemData.rsVsync;
210  // @ts-ignore
211  frameJanks.rsDur[index] = itemData.rsDur;
212  // @ts-ignore
213  frameJanks.rsIpId[index] = itemData.rsIpid;
214  // @ts-ignore
215  frameJanks.rsPid[index] = itemData.rsPid;
216  // @ts-ignore
217  frameJanks.rsName[index] = itemData.rsName;
218  // @ts-ignore
219  frameJanks.depth[index] = itemData.depth;
220}
221function setResults(transfer: boolean, frameJanks: FrameJanks): unknown {
222  return transfer
223    ? {
224        id: frameJanks.id.buffer,
225        ipid: frameJanks.ipId.buffer,
226        name: frameJanks.name.buffer,
227        app_dur: frameJanks.appDur.buffer,
228        dur: frameJanks.dur.buffer,
229        ts: frameJanks.ts.buffer,
230        jank_tag: frameJanks.jankTag.buffer,
231        pid: frameJanks.pid.buffer,
232        rs_ts: frameJanks.rsTs.buffer,
233        rs_vsync: frameJanks.rsVsync.buffer,
234        rs_dur: frameJanks.rsDur.buffer,
235        rs_ipid: frameJanks.rsIpId.buffer,
236        rs_pid: frameJanks.rsPid.buffer,
237        rs_name: frameJanks.rsName.buffer,
238        depth: frameJanks.depth.buffer,
239      }
240    : {};
241}
242function postFrameJanksMessage(data: unknown, transfer: boolean, frameJanks: FrameJanks, len: number): void {
243  let results = setResults(transfer, frameJanks);
244  (self as unknown as Worker).postMessage(
245    {
246      // @ts-ignore
247      id: data.id,
248      // @ts-ignore
249      action: data.action,
250      results: results,
251      len: len,
252      transfer: transfer,
253    },
254    transfer
255      ? [
256          frameJanks.id.buffer,
257          frameJanks.ipId.buffer,
258          frameJanks.name.buffer,
259          frameJanks.appDur.buffer,
260          frameJanks.dur.buffer,
261          frameJanks.ts.buffer,
262          frameJanks.jankTag.buffer,
263          frameJanks.pid.buffer,
264          frameJanks.rsTs.buffer,
265          frameJanks.rsVsync.buffer,
266          frameJanks.rsDur.buffer,
267          frameJanks.rsIpId.buffer,
268          frameJanks.rsPid.buffer,
269          frameJanks.rsName.buffer,
270          frameJanks.depth.buffer,
271        ]
272      : []
273  );
274}
275class FrameJanks {
276  id: Uint16Array;
277  ipId: Uint16Array;
278  name: Int32Array;
279  appDur: Float64Array;
280  dur: Float64Array;
281  ts: Float64Array;
282  jankTag: Uint16Array;
283  pid: Uint16Array;
284  rsTs: Float64Array;
285  rsVsync: Int32Array;
286  rsDur: Float64Array;
287  rsIpId: Uint16Array;
288  rsPid: Uint16Array;
289  rsName: Int32Array;
290  depth: Uint16Array;
291  constructor(data: unknown, transfer: boolean, len: number) {
292    // @ts-ignore
293    this.id = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.id);
294    // @ts-ignore
295    this.ipId = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.ipid);
296    // @ts-ignore
297    this.name = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.name);
298    // @ts-ignore
299    this.appDur = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.app_dur);
300    // @ts-ignore
301    this.dur = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.dur);
302    // @ts-ignore
303    this.ts = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.ts);
304    // @ts-ignore
305    this.jankTag = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.jank_tag);
306    // @ts-ignore
307    this.pid = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.pid);
308    // @ts-ignore
309    this.rsTs = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.rs_ts);
310    // @ts-ignore
311    this.rsVsync = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.rs_vsync);
312    // @ts-ignore
313    this.rsDur = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.rs_dur);
314    // @ts-ignore
315    this.rsIpId = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.rs_ipid);
316    // @ts-ignore
317    this.rsPid = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.rs_pid);
318    // @ts-ignore
319    this.rsName = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.rs_name);
320    // @ts-ignore
321    this.depth = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.depth);
322  }
323}
324