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 } 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, 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<any>, 60 sdkSliceFilters: Array<any>, 61 startNS: number, 62 endNS: number, 63 totalNS: number, 64 frame: any, 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 if ((item.end_ts || 0) > startNS && (item.start_ts || 0) < endNS) { 71 SdkSliceStruct.setSdkSliceFrame(sdkSliceFilters[index], 5, startNS, endNS, totalNS, frame); 72 } else { 73 sdkSliceFilters[index].frame = null; 74 } 75 } 76 return; 77 } 78 sdkSliceFilters.length = 0; 79 if (sdkList) { 80 setSdkSliceFilter(sdkList, sdkSliceFilters, startNS, endNS, totalNS, frame); 81 } 82 } 83} 84function setSdkSliceFilter( 85 sdkList: Array<any>, 86 sdkSliceFilters: Array<any>, 87 startNS: number, 88 endNS: number, 89 totalNS: number, 90 frame: any 91) { 92 for (let index = 0; index < sdkList.length; index++) { 93 let item = sdkList[index]; 94 if (item.start_ts >= startNS && item.end_ts === 0) { 95 item.end_ts = endNS; 96 } 97 if ((item.end_ts || 0) > startNS && (item.start_ts || 0) < endNS) { 98 SdkSliceStruct.setSdkSliceFrame(sdkList[index], 5, startNS, endNS, totalNS, frame); 99 if ( 100 !( 101 index > 0 && 102 (sdkList[index - 1].frame?.x || 0) === (sdkList[index].frame?.x || 0) && 103 (sdkList[index - 1].frame?.width || 0) === (sdkList[index].frame?.width || 0) 104 ) 105 ) { 106 sdkSliceFilters.push(item); 107 } 108 } 109 } 110} 111 112export class SdkSliceStruct extends BaseStruct { 113 static maxSdkSlice: number = 0; 114 static maxSdkSliceName: string = ''; 115 static hoverSdkSliceStruct: SdkSliceStruct | undefined; 116 static selectSdkSliceStruct: SdkSliceStruct | undefined; 117 118 start_ts: number | undefined; 119 end_ts: number | undefined; 120 121 value: number | undefined; 122 slice_message: string | undefined; 123 124 static draw(ctx: CanvasRenderingContext2D, data: SdkSliceStruct) { 125 if (data.frame) { 126 let width = data.frame.width || 0; 127 let index = 4; 128 ctx.fillStyle = '#6DC0DC'; 129 ctx.strokeStyle = '#6DC0DC'; 130 if (data.start_ts === SdkSliceStruct.hoverSdkSliceStruct?.start_ts) { 131 ctx.lineWidth = 1; 132 ctx.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height - 10); 133 ctx.beginPath(); 134 ctx.arc(data.frame.x, data.frame.y + 4, 3, 0, 2 * Math.PI, true); 135 ctx.fill(); 136 ctx.globalAlpha = 1.0; 137 ctx.stroke(); 138 ctx.beginPath(); 139 ctx.moveTo(data.frame.x + 3, data.frame.y + 4); 140 ctx.lineWidth = 3; 141 ctx.lineTo(data.frame.x + width, data.frame.y + 4); 142 ctx.stroke(); 143 } else { 144 ctx.lineWidth = 1; 145 ctx.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height - 10); 146 } 147 } 148 } 149 150 static setSdkSliceFrame( 151 SdkSliceNode: any, 152 padding: number, 153 startNS: number, 154 endNS: number, 155 totalNS: number, 156 frame: any 157 ): void { 158 let sdkSliceStartPointX: number, sdkSliceEndPointX: number; 159 160 if ((SdkSliceNode.start_ts || 0) < startNS) { 161 sdkSliceStartPointX = 0; 162 } else { 163 sdkSliceStartPointX = ns2x(SdkSliceNode.start_ts || 0, startNS, endNS, totalNS, frame); 164 } 165 if ((SdkSliceNode.end_ts || 0) > endNS) { 166 sdkSliceEndPointX = frame.width; 167 } else { 168 sdkSliceEndPointX = ns2x(SdkSliceNode.end_ts || 0, startNS, endNS, totalNS, frame); 169 } 170 let frameWidth: number = sdkSliceEndPointX - sdkSliceStartPointX <= 1 ? 1 : sdkSliceEndPointX - sdkSliceStartPointX; 171 if (!SdkSliceNode.frame) { 172 SdkSliceNode.frame = {}; 173 } 174 SdkSliceNode.frame.x = Math.floor(sdkSliceStartPointX); 175 SdkSliceNode.frame.y = frame.y + padding; 176 SdkSliceNode.frame.width = Math.ceil(frameWidth); 177 SdkSliceNode.frame.height = Math.floor(frame.height - padding * 2); 178 } 179} 180