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 { Render, BaseStruct, isFrameContainPoint, ns2x, Rect } from './ProcedureWorkerCommon'; 17import { TraceRow } from '../../component/trace/base/TraceRow'; 18 19export class SdkSliceRender extends Render { 20 renderMainThread( 21 req: { 22 context: CanvasRenderingContext2D; 23 useCache: boolean; 24 type: string; 25 maxName: string; 26 maxValue: number; 27 }, 28 row: TraceRow<SdkSliceStruct> 29 ): void { 30 let sdkList = row.dataList; 31 let sdkFilter = row.dataListCache; 32 SdkSliceStruct.maxSdkSlice = req.maxValue; 33 SdkSliceStruct.maxSdkSliceName = req.maxName; 34 this.sdkSlice( 35 sdkList, 36 sdkFilter, 37 TraceRow.range?.startNS ?? 0, 38 TraceRow.range?.endNS ?? 0, 39 TraceRow.range?.totalNS ?? 0, // @ts-ignore 40 row.frame, 41 req.useCache || (TraceRow.range?.refresh ?? false) 42 ); 43 req.context.beginPath(); 44 let sdkSliceFind = false; 45 for (let re of sdkFilter) { 46 if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { 47 SdkSliceStruct.hoverSdkSliceStruct = re; 48 sdkSliceFind = true; 49 } 50 SdkSliceStruct.draw(req.context, re); 51 } 52 if (!sdkSliceFind && row.isHover) { 53 SdkSliceStruct.hoverSdkSliceStruct = undefined; 54 } 55 req.context.closePath(); 56 } 57 58 sdkSlice( 59 sdkList: Array<unknown>, 60 sdkSliceFilters: Array<unknown>, 61 startNS: number, 62 endNS: number, 63 totalNS: number, 64 frame: Rect, 65 use: boolean 66 ): void { 67 if (use && sdkSliceFilters.length > 0) { 68 for (let index = 0; index < sdkSliceFilters.length; index++) { 69 let item = sdkSliceFilters[index]; 70 //@ts-ignore 71 if ((item.end_ts || 0) > startNS && (item.start_ts || 0) < endNS) { 72 SdkSliceStruct.setSdkSliceFrame(sdkSliceFilters[index], 5, startNS, endNS, totalNS, frame); 73 } else { 74 //@ts-ignore 75 sdkSliceFilters[index].frame = null; 76 } 77 } 78 return; 79 } 80 sdkSliceFilters.length = 0; 81 if (sdkList) { 82 setSdkSliceFilter(sdkList, sdkSliceFilters, startNS, endNS, totalNS, frame); 83 } 84 } 85} 86function setSdkSliceFilter( 87 sdkList: Array<unknown>, 88 sdkSliceFilters: Array<unknown>, 89 startNS: number, 90 endNS: number, 91 totalNS: number, 92 frame: Rect 93): void { 94 for (let index = 0; index < sdkList.length; index++) { 95 let item = sdkList[index]; 96 //@ts-ignore 97 if (item.start_ts >= startNS && item.end_ts === 0) { 98 //@ts-ignore 99 item.end_ts = endNS; 100 } 101 //@ts-ignore 102 if ((item.end_ts || 0) > startNS && (item.start_ts || 0) < endNS) { 103 SdkSliceStruct.setSdkSliceFrame(sdkList[index], 5, startNS, endNS, totalNS, frame); 104 if ( 105 !( 106 index > 0 && 107 //@ts-ignore 108 (sdkList[index - 1].frame?.x || 0) === (sdkList[index].frame?.x || 0) && 109 //@ts-ignore 110 (sdkList[index - 1].frame?.width || 0) === (sdkList[index].frame?.width || 0) 111 ) 112 ) { 113 sdkSliceFilters.push(item); 114 } 115 } 116 } 117} 118 119export class SdkSliceStruct extends BaseStruct { 120 static maxSdkSlice: number = 0; 121 static maxSdkSliceName: string = ''; 122 static hoverSdkSliceStruct: SdkSliceStruct | undefined; 123 static selectSdkSliceStruct: SdkSliceStruct | undefined; 124 125 startTs: number | undefined; 126 endTs: number | undefined; 127 128 value: number | undefined; 129 slice_message: string | undefined; 130 131 static draw(ctx: CanvasRenderingContext2D, data: SdkSliceStruct): void { 132 if (data.frame) { 133 let width = data.frame.width || 0; 134 ctx.fillStyle = '#6DC0DC'; 135 ctx.strokeStyle = '#6DC0DC'; 136 if (data.startTs === SdkSliceStruct.hoverSdkSliceStruct?.startTs) { 137 ctx.lineWidth = 1; 138 ctx.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height - 10); 139 ctx.beginPath(); 140 ctx.arc(data.frame.x, data.frame.y + 4, 3, 0, 2 * Math.PI, true); 141 ctx.fill(); 142 ctx.globalAlpha = 1.0; 143 ctx.stroke(); 144 ctx.beginPath(); 145 ctx.moveTo(data.frame.x + 3, data.frame.y + 4); 146 ctx.lineWidth = 3; 147 ctx.lineTo(data.frame.x + width, data.frame.y + 4); 148 ctx.stroke(); 149 } else { 150 ctx.lineWidth = 1; 151 ctx.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height - 10); 152 } 153 } 154 } 155 156 static setSdkSliceFrame( 157 SdkSliceNode: unknown, 158 padding: number, 159 startNS: number, 160 endNS: number, 161 totalNS: number, 162 frame: Rect 163 ): void { 164 let sdkSliceStartPointX: number; 165 let sdkSliceEndPointX: number; 166 //@ts-ignore 167 if ((SdkSliceNode.start_ts || 0) < startNS) { 168 sdkSliceStartPointX = 0; 169 } else { 170 //@ts-ignore 171 sdkSliceStartPointX = ns2x(SdkSliceNode.start_ts || 0, startNS, endNS, totalNS, frame); 172 } 173 //@ts-ignore 174 if ((SdkSliceNode.end_ts || 0) > endNS) { 175 sdkSliceEndPointX = frame.width; 176 } else { 177 //@ts-ignore 178 sdkSliceEndPointX = ns2x(SdkSliceNode.end_ts || 0, startNS, endNS, totalNS, frame); 179 } 180 let frameWidth: number = sdkSliceEndPointX - sdkSliceStartPointX <= 1 ? 1 : sdkSliceEndPointX - sdkSliceStartPointX; 181 //@ts-ignore 182 if (!SdkSliceNode.frame) { 183 //@ts-ignore 184 SdkSliceNode.frame = {}; 185 } 186 //@ts-ignore 187 SdkSliceNode.frame.x = Math.floor(sdkSliceStartPointX); 188 //@ts-ignore 189 SdkSliceNode.frame.y = frame.y + padding; 190 //@ts-ignore 191 SdkSliceNode.frame.width = Math.ceil(frameWidth); 192 //@ts-ignore 193 SdkSliceNode.frame.height = Math.floor(frame.height - padding * 2); 194 } 195} 196