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 { SpSystemTrace } from '../../component/SpSystemTrace'; 19 20export class SnapShotRender { 21 renderMainThread( 22 req: { 23 snapShotContext: CanvasRenderingContext2D; 24 useCache: boolean; 25 type: string; 26 translateY: number; 27 }, 28 snapShotRow: TraceRow<SnapShotStruct>, 29 trace: SpSystemTrace 30 ): void { 31 let list = snapShotRow.dataList; 32 let filter = snapShotRow.dataListCache; 33 dataFilterHandler(list, filter, { 34 startKey: 'startTime', 35 durKey: 'dur', 36 startNS: TraceRow.range?.startNS ?? 0, 37 endNS: TraceRow.range?.endNS ?? 0, 38 totalNS: TraceRow.range?.totalNS ?? 0, 39 frame: snapShotRow.frame, 40 paddingTop: 5, 41 useCache: req.useCache || !(TraceRow.range?.refresh ?? false), 42 }); 43 req.snapShotContext.globalAlpha = 0.6; 44 let find = false; 45 let offset = 3; 46 for (let re of filter) { 47 SnapShotStruct.draw(req.snapShotContext, re, snapShotRow.translateY); 48 if (snapShotRow.isHover) { 49 if ( 50 re.frame && 51 snapShotRow.hoverX >= re.frame.x - offset && 52 snapShotRow.hoverX <= re.frame.x + re.frame.width + offset 53 ) { 54 SnapShotStruct.hoverSnapShotStruct = re; 55 find = true; 56 } 57 } 58 } 59 if (!find && snapShotRow.isHover) { 60 SnapShotStruct.hoverSnapShotStruct = undefined; 61 } 62 } 63} 64 65export class SnapShotStruct extends BaseStruct { 66 static hoverSnapShotStruct: SnapShotStruct | undefined; 67 static selectSnapShotStruct: SnapShotStruct | undefined; 68 static maxVal: number | undefined = 0; 69 static index = 0; 70 static maxDepth: number = 0; 71 static imageCache: { [img: string]: Promise<HTMLImageElement> } = {}; 72 73 value: number | undefined = 20; 74 startTime: number | undefined; 75 dur: number | undefined; 76 img: string = ''; 77 78 static async draw( 79 ctx: CanvasRenderingContext2D, 80 data: SnapShotStruct, 81 translateY: number 82 ): Promise<void> { 83 if (data.frame && data.img) { 84 const imagePromise = SnapShotStruct.getImageFromCache(data.img); 85 try { 86 const image = await imagePromise; 87 ctx.drawImage( 88 image, 89 data.frame.x, 90 data.frame.y + translateY, 91 data.frame.width, 92 data.frame.height 93 ); 94 } catch (error) { 95 console.error('Error loading image:', error); 96 } 97 } 98 } 99 private static async getImageFromCache(img: string): Promise<HTMLImageElement> { 100 if (!SnapShotStruct.imageCache[img]) { 101 SnapShotStruct.imageCache[img] = new Promise((resolve, reject) => { 102 const image = new Image(); 103 image.onload = (): void => resolve(image); 104 image.onerror = (error): void => reject(new Error(`Failed to load image: ${img},${error}`)); 105 image.src = img; 106 }); 107 } 108 return SnapShotStruct.imageCache[img]; 109 } 110}