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 { FrameAnimationStruct } from '../ui-worker/ProcedureWorkerFrameAnimation'; 16import { FrameSpacingStruct } from '../ui-worker/ProcedureWorkerFrameSpacing'; 17import { Args } from './CommonArgs'; 18 19export const chartFrameAnimationDataProtoSql = (args: Args): string => { 20 return ` 21 SELECT 22 a.id AS animationId, 23 0 AS status, 24 ( 25 CASE WHEN a.input_time NOT NULL 26 THEN ( a.input_time - ${args.recordStartNS} ) 27 ELSE ( a.start_point - ${args.recordStartNS} ) 28 END 29 ) AS startTs, 30 ( a.start_point - ${args.recordStartNS} ) AS endTs, 31 a.name AS name 32 FROM 33 animation AS a 34 UNION 35 SELECT 36 a.id AS animationId, 37 1 AS status, 38 ( 39 CASE WHEN a.input_time NOT NULL 40 THEN ( a.input_time - ${args.recordStartNS} ) 41 ELSE ( a.start_point - ${args.recordStartNS} ) 42 END 43 ) AS startTs, 44 ( a.end_point - ${args.recordStartNS} ) AS endTs, 45 a.name AS name 46 FROM 47 animation AS a;`; 48}; 49 50export const chartFrameDynamicDataMemSql = (args: Args): string => { 51 return ` 52 SELECT 53 dy.id, 54 dy.x, 55 dy.y, 56 dy.width, 57 dy.height, 58 dy.alpha, 59 (dy.end_time - ${args.recordStartNS}) AS ts, 60 dy.name as appName 61 FROM 62 dynamic_frame AS dy 63 WHERE ts >= ${Math.floor(args.startNS)} 64 and ts <= ${Math.floor(args.endNS)}`; 65}; 66 67export const chartFrameSpacingDataMemSql = (args: Args): string => { 68 return ` 69 SELECT 70 d.id, 71 d.x, 72 d.y, 73 d.width AS currentFrameWidth, 74 d.height AS currentFrameHeight, 75 (d.end_time - ${args.recordStartNS}) AS currentTs, 76 d.name AS nameId 77 FROM 78 dynamic_frame AS d 79 WHERE currentTs >= ${Math.floor(args.startNS)} 80 and currentTs <= ${Math.floor(args.endNS)};`; 81}; 82 83export function frameAnimationReceiver(data: unknown, proc: Function): void { 84 // @ts-ignore 85 let res = proc(chartFrameAnimationDataProtoSql(data.params)); 86 // @ts-ignore 87 let transfer = data.params.trafic !== TraficEnum.SharedArrayBuffer; 88 let frameAnimation = new FrameAnimation(data, res, transfer); 89 let unitIndex: number = 1; 90 let isIntersect = (a: FrameAnimationStruct, b: FrameAnimationStruct): boolean => 91 Math.max(a.startTs! + a.dur!, b.startTs! + b.dur!) - Math.min(a.startTs!, b.startTs!) < a.dur! + b.dur!; 92 let depths: unknown[] = []; 93 for (let index: number = 0; index < res.length; index++) { 94 let itemData = res[index]; 95 // @ts-ignore 96 data.params.trafic === TraficEnum.ProtoBuffer && (itemData = itemData.frameAnimationData); 97 itemData.dur = itemData.endTs - itemData.startTs; 98 if (!itemData.dur || itemData.dur < 0) { 99 continue; 100 } 101 if (depths.length === 0) { 102 itemData.depth = 0; 103 depths[0] = itemData; 104 } else { 105 let depthIndex: number = 0; 106 let isContinue: boolean = true; 107 while (isContinue) { 108 // @ts-ignore 109 if (isIntersect(depths[depthIndex], itemData)) { 110 if (depths[depthIndex + unitIndex] === undefined || !depths[depthIndex + unitIndex]) { 111 itemData.depth = depthIndex + unitIndex; 112 depths[depthIndex + unitIndex] = itemData; 113 isContinue = false; 114 } 115 } else { 116 itemData.depth = depthIndex; 117 depths[depthIndex] = itemData; 118 isContinue = false; 119 } 120 depthIndex++; 121 } 122 } 123 frameAnimation.animationId[index] = itemData.animationId; 124 frameAnimation.status[index] = itemData.status; 125 frameAnimation.startTs[index] = itemData.startTs; 126 frameAnimation.endTs[index] = itemData.endTs; 127 frameAnimation.dur[index] = itemData.dur; 128 frameAnimation.depth[index] = itemData.depth; 129 } 130 postFrameAnimationMessage(data, transfer, frameAnimation, res.length); 131} 132function postFrameAnimationMessage( 133 data: unknown, 134 transfer: boolean, 135 frameAnimation: FrameAnimation, 136 len: number 137): void { 138 (self as unknown as Worker).postMessage( 139 { 140 // @ts-ignore 141 id: data.id, 142 // @ts-ignore 143 action: data.action, 144 results: transfer 145 ? { 146 animationId: frameAnimation.animationId.buffer, 147 status: frameAnimation.status.buffer, 148 startTs: frameAnimation.startTs.buffer, 149 endTs: frameAnimation.endTs.buffer, 150 dur: frameAnimation.dur.buffer, 151 depth: frameAnimation.depth.buffer, 152 } 153 : {}, 154 len: len, 155 transfer: transfer, 156 }, 157 transfer 158 ? [ 159 frameAnimation.animationId.buffer, 160 frameAnimation.status.buffer, 161 frameAnimation.startTs.buffer, 162 frameAnimation.endTs.buffer, 163 frameAnimation.dur.buffer, 164 frameAnimation.depth.buffer, 165 ] 166 : [] 167 ); 168} 169class FrameAnimation { 170 animationId: Uint16Array; 171 status: Uint16Array; 172 startTs: Float64Array; 173 endTs: Float64Array; 174 dur: Float64Array; 175 depth: Uint16Array; 176 177 constructor(data: unknown, res: unknown[], transfer: boolean) { 178 // @ts-ignore 179 this.animationId = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.animationId); 180 // @ts-ignore 181 this.status = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.status); 182 // @ts-ignore 183 this.startTs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startTs); 184 // @ts-ignore 185 this.endTs = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.endTs); 186 // @ts-ignore 187 this.dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur); 188 // @ts-ignore 189 this.depth = new Uint16Array(transfer ? res.length : data.params.sharedArrayBuffers.depth); 190 } 191} 192 193let frameSpacingList: Array<unknown> = []; 194let frameDynamic: Array<unknown> = []; 195export function resetDynamicEffect(): void { 196 frameSpacingList = []; 197 frameDynamic = []; 198} 199export function frameDynamicReceiver(data: unknown, proc: Function): void { 200 if (frameDynamic.length === 0) { 201 // @ts-ignore 202 frameDynamic = proc(chartFrameDynamicDataMemSql(data.params)); 203 } 204 // @ts-ignore 205 let transfer = data.params.trafic !== TraficEnum.SharedArrayBuffer; 206 // @ts-ignore 207 let id = new Uint16Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.id); 208 // @ts-ignore 209 let x = new Float32Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.x); 210 // @ts-ignore 211 let y = new Float32Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.y); 212 // @ts-ignore 213 let width = new Float32Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.width); 214 // @ts-ignore 215 let height = new Float32Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.height); 216 // @ts-ignore 217 let alpha = new Float32Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.alpha); 218 // @ts-ignore 219 let ts = new Float64Array(transfer ? frameDynamic.length : data.params.sharedArrayBuffers.ts); 220 for (let index: number = 0; index < frameDynamic.length; index++) { 221 let itemData = frameDynamic[index]; 222 // @ts-ignore 223 data.params.trafic === TraficEnum.ProtoBuffer && (itemData = itemData.frameDynamicData); 224 // @ts-ignore 225 id[index] = itemData.id; 226 // @ts-ignore 227 x[index] = Number(itemData.x); 228 // @ts-ignore 229 y[index] = Number(itemData.y); 230 // @ts-ignore 231 width[index] = Number(itemData.width); 232 // @ts-ignore 233 height[index] = Number(itemData.height); 234 // @ts-ignore 235 alpha[index] = Number(itemData.alpha); 236 // @ts-ignore 237 ts[index] = itemData.ts; 238 } 239 (self as unknown as Worker).postMessage( 240 { 241 // @ts-ignore 242 id: data.id, 243 // @ts-ignore 244 action: data.action, 245 results: transfer 246 ? { 247 id: id.buffer, 248 x: x.buffer, 249 y: y.buffer, 250 width: width.buffer, 251 height: height.buffer, 252 alpha: alpha.buffer, 253 ts: ts.buffer, 254 } 255 : {}, 256 len: frameDynamic.length, 257 transfer: transfer, 258 }, 259 transfer ? [id.buffer, x.buffer, y.buffer, width.buffer, height.buffer, alpha.buffer, ts.buffer] : [] 260 ); 261} 262export function frameSpacingReceiver(data: unknown, proc: Function): void { 263 if (frameSpacingList.length === 0) { 264 // @ts-ignore 265 frameSpacingList = proc(chartFrameSpacingDataMemSql(data.params)); 266 } 267 // @ts-ignore 268 let transfer = data.params.trafic !== TraficEnum.SharedArrayBuffer; 269 let frameSpacing = new FrameSpacing(data, frameSpacingList, transfer); 270 let nameDataMap: Map<string, Array<FrameSpacingStruct>> = new Map(); 271 for (let index: number = 0; index < frameSpacingList.length; index++) { 272 let itemData = frameSpacingList[index]; 273 // @ts-ignore 274 data.params.trafic === TraficEnum.ProtoBuffer && (itemData = itemData.frameSpacingData); 275 // @ts-ignore 276 if (nameDataMap.has(itemData.nameId)) { 277 // @ts-ignore 278 setSpacingStructs(nameDataMap, itemData, data); 279 } else { 280 // @ts-ignore 281 setNameDataMap(nameDataMap, itemData); 282 } 283 // @ts-ignore 284 frameSpacing.id[index] = itemData.id; 285 // @ts-ignore 286 frameSpacing.x[index] = Number(itemData.x); 287 // @ts-ignore 288 frameSpacing.y[index] = Number(itemData.y); 289 // @ts-ignore 290 frameSpacing.currentFrameWidth[index] = Number(itemData.currentFrameWidth); 291 // @ts-ignore 292 frameSpacing.currentFrameHeight[index] = Number(itemData.currentFrameHeight); 293 // @ts-ignore 294 frameSpacing.currentTs[index] = itemData.currentTs; 295 // @ts-ignore 296 frameSpacing.frameSpacingResult[index] = Number(itemData.frameSpacingResult); 297 // @ts-ignore 298 frameSpacing.preTs[index] = itemData.preTs; 299 // @ts-ignore 300 frameSpacing.preFrameWidth[index] = Number(itemData.preFrameWidth); 301 // @ts-ignore 302 frameSpacing.preFrameHeight[index] = Number(itemData.preFrameHeight); 303 // @ts-ignore 304 frameSpacing.preX[index] = Number(itemData.preX); 305 // @ts-ignore 306 frameSpacing.preY[index] = Number(itemData.preY); 307 } 308 postFrameSpacingMessage(data, transfer, frameSpacing, frameSpacingList.length); 309} 310function postFrameSpacingMessage(data: unknown, transfer: boolean, frameSpacing: FrameSpacing, len: number): void { 311 (self as unknown as Worker).postMessage( 312 { 313 // @ts-ignore 314 id: data.id, 315 // @ts-ignore 316 action: data.action, 317 results: transfer 318 ? { 319 id: frameSpacing.id.buffer, 320 x: frameSpacing.x.buffer, 321 y: frameSpacing.y.buffer, 322 currentFrameWidth: frameSpacing.currentFrameWidth.buffer, 323 currentFrameHeight: frameSpacing.currentFrameHeight.buffer, 324 currentTs: frameSpacing.currentTs.buffer, 325 frameSpacingResult: frameSpacing.frameSpacingResult.buffer, 326 preTs: frameSpacing.preTs.buffer, 327 preFrameWidth: frameSpacing.preFrameWidth.buffer, 328 preFrameHeight: frameSpacing.preFrameHeight.buffer, 329 preX: frameSpacing.preX.buffer, 330 preY: frameSpacing.preY.buffer, 331 } 332 : {}, 333 len: len, 334 transfer: transfer, 335 }, 336 transfer 337 ? [ 338 frameSpacing.id.buffer, 339 frameSpacing.x.buffer, 340 frameSpacing.y.buffer, 341 frameSpacing.currentFrameWidth.buffer, 342 frameSpacing.currentFrameHeight.buffer, 343 frameSpacing.currentTs.buffer, 344 frameSpacing.frameSpacingResult.buffer, 345 frameSpacing.preTs.buffer, 346 frameSpacing.preFrameWidth.buffer, 347 frameSpacing.preFrameHeight.buffer, 348 frameSpacing.preX.buffer, 349 frameSpacing.preY.buffer, 350 ] 351 : [] 352 ); 353} 354function setSpacingStructs( 355 nameDataMap: Map<string, Array<FrameSpacingStruct>>, 356 itemData: FrameSpacingStruct, 357 data: unknown 358): void { 359 let unitIndex: number = 1; 360 let secondToNanosecond: number = 1000_000_000; 361 let spacingStructs = nameDataMap.get(itemData.nameId!); 362 if (spacingStructs) { 363 let lastIndexData = spacingStructs[spacingStructs.length - 1]; 364 let intervalTime = (itemData.currentTs - lastIndexData.currentTs) / secondToNanosecond; 365 let widthDifference = Number(itemData.currentFrameWidth!) - Number(lastIndexData.currentFrameWidth!); 366 let heightDifference = Number(itemData.currentFrameHeight!) - Number(lastIndexData.currentFrameHeight!); 367 let xDifference = Number(itemData.x!) - Number(lastIndexData.x!); 368 let yDifference = Number(itemData.y!) - Number(lastIndexData.y!); 369 // @ts-ignore 370 let frameWidth = Math.abs(widthDifference / data.params.physicalWidth / intervalTime); 371 // @ts-ignore 372 let frameHeight = Math.abs(heightDifference / data.params.physicalHeight / intervalTime); 373 // @ts-ignore 374 let frameX = Math.abs(xDifference / data.params.physicalWidth / intervalTime); 375 // @ts-ignore 376 let frameY = Math.abs(yDifference / data.params.physicalHeight / intervalTime); 377 let result = Math.max(frameWidth, frameHeight, frameX, frameY); 378 itemData.frameSpacingResult = Number(result.toFixed(unitIndex)); 379 itemData.preTs = lastIndexData.currentTs; 380 itemData.preFrameWidth = Number(lastIndexData.currentFrameWidth); 381 itemData.preFrameHeight = Number(lastIndexData.currentFrameHeight); 382 itemData.preX = Number(lastIndexData.x); 383 itemData.preY = Number(lastIndexData.y); 384 spacingStructs.push(itemData); 385 } 386} 387function setNameDataMap(nameDataMap: Map<string, Array<FrameSpacingStruct>>, itemData: FrameSpacingStruct): void { 388 itemData.frameSpacingResult = 0; 389 itemData.preTs = 0; 390 itemData.preFrameWidth = 0; 391 itemData.preFrameHeight = 0; 392 itemData.preX = 0; 393 itemData.preY = 0; 394 nameDataMap.set(itemData.nameId!, [itemData]); 395} 396class FrameSpacing { 397 id: Uint16Array; 398 x: Float32Array; 399 y: Float32Array; 400 currentFrameWidth: Float32Array; 401 currentFrameHeight: Float32Array; 402 currentTs: Float64Array; 403 frameSpacingResult: Float32Array; 404 preTs: Float64Array; 405 preFrameWidth: Float32Array; 406 preFrameHeight: Float32Array; 407 preX: Float32Array; 408 preY: Float32Array; 409 410 constructor(data: unknown, len: unknown[], transfer: boolean) { 411 // @ts-ignore 412 this.id = new Uint16Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 413 // @ts-ignore 414 this.x = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 415 // @ts-ignore 416 this.y = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 417 // @ts-ignore 418 this.currentFrameWidth = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 419 // @ts-ignore 420 this.currentFrameHeight = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 421 // @ts-ignore 422 this.currentTs = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 423 // @ts-ignore 424 this.frameSpacingResult = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 425 // @ts-ignore 426 this.preTs = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 427 // @ts-ignore 428 this.preFrameWidth = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 429 // @ts-ignore 430 this.preFrameHeight = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 431 // @ts-ignore 432 this.preX = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 433 // @ts-ignore 434 this.preY = new Float32Array(transfer ? len : data.params.sharedArrayBuffers.animationId); 435 } 436} 437