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 { 17 drawFlagLine, 18 drawLines, 19 drawLoading, 20 drawWakeUp, 21 Render, 22 RequestMessage, 23 BaseStruct, 24 isFrameContainPoint, 25 ns2x, 26 drawSelection, 27} from './ProcedureWorkerCommon.js'; 28import { TraceRow } from '../../component/trace/base/TraceRow.js'; 29import { CounterStruct } from './ProduceWorkerSdkCounter.js'; 30 31export class SdkSliceRender extends Render { 32 renderMainThread( 33 req: { 34 context: CanvasRenderingContext2D; 35 useCache: boolean; 36 type: string; 37 maxName: string; 38 maxValue: number; 39 }, 40 row: TraceRow<SdkSliceStruct> 41 ): void { 42 let sdkList = row.dataList; 43 let sdkFilter = row.dataListCache; 44 SdkSliceStruct.maxSdkSlice = req.maxValue; 45 SdkSliceStruct.maxSdkSliceName = req.maxName; 46 this.sdkSlice( 47 sdkList, 48 sdkFilter, 49 TraceRow.range?.startNS ?? 0, 50 TraceRow.range?.endNS ?? 0, 51 TraceRow.range?.totalNS ?? 0, 52 row.frame, 53 req.useCache || (TraceRow.range?.refresh ?? false) 54 ); 55 req.context.beginPath(); 56 let sdkSliceFind = false; 57 for (let re of sdkFilter) { 58 if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { 59 SdkSliceStruct.hoverSdkSliceStruct = re; 60 sdkSliceFind = true; 61 } 62 SdkSliceStruct.draw(req.context, re); 63 } 64 if (!sdkSliceFind && row.isHover) { 65 SdkSliceStruct.hoverSdkSliceStruct = undefined; 66 } 67 req.context.closePath(); 68 } 69 70 render(sdkSliceRequest: RequestMessage, sdkList: Array<any>, filter: Array<any>): void { 71 if (sdkSliceRequest.lazyRefresh) { 72 this.sdkSlice( 73 sdkList, 74 filter, 75 sdkSliceRequest.startNS, 76 sdkSliceRequest.endNS, 77 sdkSliceRequest.totalNS, 78 sdkSliceRequest.frame, 79 sdkSliceRequest.useCache || !sdkSliceRequest.range.refresh 80 ); 81 } else { 82 if (!sdkSliceRequest.useCache) { 83 this.sdkSlice( 84 sdkList, 85 filter, 86 sdkSliceRequest.startNS, 87 sdkSliceRequest.endNS, 88 sdkSliceRequest.totalNS, 89 sdkSliceRequest.frame, 90 false 91 ); 92 } 93 } 94 if (sdkSliceRequest.canvas) { 95 sdkSliceRequest.context.clearRect(0, 0, sdkSliceRequest.canvas.width, sdkSliceRequest.canvas.height); 96 let sdkSliceArr = filter; 97 if ( 98 sdkSliceArr.length > 0 && 99 !sdkSliceRequest.range.refresh && 100 !sdkSliceRequest.useCache && 101 sdkSliceRequest.lazyRefresh 102 ) { 103 drawLoading( 104 sdkSliceRequest.context, 105 sdkSliceRequest.startNS, 106 sdkSliceRequest.endNS, 107 sdkSliceRequest.totalNS, 108 sdkSliceRequest.frame, 109 sdkSliceArr[0].startNS, 110 sdkSliceArr[sdkSliceArr.length - 1].startNS + sdkSliceArr[sdkSliceArr.length - 1].dur 111 ); 112 } 113 sdkSliceRequest.context.beginPath(); 114 SdkSliceStruct.maxSdkSlice = sdkSliceRequest.params.maxSdkSlice; 115 SdkSliceStruct.maxSdkSliceName = sdkSliceRequest.params.maxSdkSliceName; 116 drawLines(sdkSliceRequest.context, sdkSliceRequest.xs, sdkSliceRequest.frame.height, sdkSliceRequest.lineColor); 117 SdkSliceStruct.hoverSdkSliceStruct = undefined; 118 if (sdkSliceRequest.isHover) { 119 for (let re of filter) { 120 if ( 121 re.frame && 122 sdkSliceRequest.hoverX >= re.frame.x && 123 sdkSliceRequest.hoverX <= re.frame.x + re.frame.width && 124 sdkSliceRequest.hoverY >= re.frame.y && 125 sdkSliceRequest.hoverY <= re.frame.y + re.frame.height 126 ) { 127 SdkSliceStruct.hoverSdkSliceStruct = re; 128 break; 129 } 130 } 131 } 132 SdkSliceStruct.selectSdkSliceStruct = sdkSliceRequest.params.selectSdkSliceStruct; 133 for (let re of filter) { 134 SdkSliceStruct.draw(sdkSliceRequest.context, re); 135 } 136 drawSelection(sdkSliceRequest.context, sdkSliceRequest.params); 137 sdkSliceRequest.context.closePath(); 138 sdkSliceRequest.context.globalAlpha = 0.8; 139 sdkSliceRequest.context.fillStyle = '#f0f0f0'; 140 sdkSliceRequest.context.globalAlpha = 1; 141 sdkSliceRequest.context.fillStyle = '#333'; 142 sdkSliceRequest.context.textBaseline = 'middle'; 143 drawFlagLine( 144 sdkSliceRequest.context, 145 sdkSliceRequest.flagMoveInfo, 146 sdkSliceRequest.flagSelectedInfo, 147 sdkSliceRequest.startNS, 148 sdkSliceRequest.endNS, 149 sdkSliceRequest.totalNS, 150 sdkSliceRequest.frame, 151 sdkSliceRequest.slicesTime 152 ); 153 } 154 // @ts-ignore 155 self.postMessage({ 156 id: sdkSliceRequest.id, 157 type: sdkSliceRequest.type, 158 results: sdkSliceRequest.canvas ? undefined : filter, 159 hover: SdkSliceStruct.hoverSdkSliceStruct, 160 }); 161 } 162 163 sdkSlice( 164 sdkList: Array<any>, 165 sdkSliceFilters: Array<any>, 166 startNS: number, 167 endNS: number, 168 totalNS: number, 169 frame: any, 170 use: boolean 171 ): void { 172 if (use && sdkSliceFilters.length > 0) { 173 for (let index = 0; index < sdkSliceFilters.length; index++) { 174 let item = sdkSliceFilters[index]; 175 if ((item.end_ts || 0) > (startNS || 0) && (item.start_ts || 0) < (endNS || 0)) { 176 SdkSliceStruct.setSdkSliceFrame(sdkSliceFilters[index], 5, startNS || 0, endNS || 0, totalNS || 0, frame); 177 } else { 178 sdkSliceFilters[index].frame = null; 179 } 180 } 181 return; 182 } 183 sdkSliceFilters.length = 0; 184 if (sdkList) { 185 for (let index = 0; index < sdkList.length; index++) { 186 let item = sdkList[index]; 187 if (item.start_ts >= startNS && item.end_ts == 0) { 188 item.end_ts = endNS; 189 } 190 if ((item.end_ts || 0) > (startNS || 0) && (item.start_ts || 0) < (endNS || 0)) { 191 SdkSliceStruct.setSdkSliceFrame(sdkList[index], 5, startNS || 0, endNS || 0, totalNS || 0, frame); 192 if ( 193 index > 0 && 194 (sdkList[index - 1].frame?.x || 0) == (sdkList[index].frame?.x || 0) && 195 (sdkList[index - 1].frame?.width || 0) == (sdkList[index].frame?.width || 0) 196 ) { 197 } else { 198 sdkSliceFilters.push(item); 199 } 200 } 201 } 202 } 203 } 204} 205 206export class SdkSliceStruct extends BaseStruct { 207 static maxSdkSlice: number = 0; 208 static maxSdkSliceName: string = ''; 209 static hoverSdkSliceStruct: SdkSliceStruct | undefined; 210 static selectSdkSliceStruct: SdkSliceStruct | undefined; 211 212 start_ts: number | undefined; 213 end_ts: number | undefined; 214 215 value: number | undefined; 216 slice_message: string | undefined; 217 218 static draw(ctx: CanvasRenderingContext2D, data: SdkSliceStruct) { 219 if (data.frame) { 220 let width = data.frame.width || 0; 221 let index = 4; 222 ctx.fillStyle = '#6DC0DC'; 223 ctx.strokeStyle = '#6DC0DC'; 224 if (data.start_ts === SdkSliceStruct.hoverSdkSliceStruct?.start_ts) { 225 ctx.lineWidth = 1; 226 ctx.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height - 10); 227 ctx.beginPath(); 228 ctx.arc(data.frame.x, data.frame.y + 4, 3, 0, 2 * Math.PI, true); 229 ctx.fill(); 230 ctx.globalAlpha = 1.0; 231 ctx.stroke(); 232 ctx.beginPath(); 233 ctx.moveTo(data.frame.x + 3, data.frame.y + 4); 234 ctx.lineWidth = 3; 235 ctx.lineTo(data.frame.x + width, data.frame.y + 4); 236 ctx.stroke(); 237 } else { 238 ctx.lineWidth = 1; 239 ctx.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height - 10); 240 } 241 } 242 } 243 244 static setSdkSliceFrame( 245 SdkSliceNode: any, 246 padding: number, 247 startNS: number, 248 endNS: number, 249 totalNS: number, 250 frame: any 251 ): void { 252 let sdkSliceStartPointX: number, sdkSliceEndPointX: number; 253 254 if ((SdkSliceNode.start_ts || 0) < startNS) { 255 sdkSliceStartPointX = 0; 256 } else { 257 sdkSliceStartPointX = ns2x(SdkSliceNode.start_ts || 0, startNS, endNS, totalNS, frame); 258 } 259 if ((SdkSliceNode.end_ts || 0) > endNS) { 260 sdkSliceEndPointX = frame.width; 261 } else { 262 sdkSliceEndPointX = ns2x(SdkSliceNode.end_ts || 0, startNS, endNS, totalNS, frame); 263 } 264 let frameWidth: number = sdkSliceEndPointX - sdkSliceStartPointX <= 1 ? 1 : sdkSliceEndPointX - sdkSliceStartPointX; 265 if (!SdkSliceNode.frame) { 266 SdkSliceNode.frame = {}; 267 } 268 SdkSliceNode.frame.x = Math.floor(sdkSliceStartPointX); 269 SdkSliceNode.frame.y = frame.y + padding; 270 SdkSliceNode.frame.width = Math.ceil(frameWidth); 271 SdkSliceNode.frame.height = Math.floor(frame.height - padding * 2); 272 } 273} 274