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 dataFilterHandler, 18 BaseStruct, 19 isFrameContainPoint, 20 Render, 21 RequestMessage, 22 drawString, 23 drawLoadingFrame, 24} from './ProcedureWorkerCommon'; 25import { TraceRow } from '../../component/trace/base/TraceRow'; 26import { ColorUtils } from '../../component/trace/base/ColorUtils'; 27import { SpSystemTrace } from '../../component/SpSystemTrace'; 28 29export class ThreadSysCallRender extends Render { 30 renderMainThread( 31 threadReq: { 32 context: CanvasRenderingContext2D; 33 useCache: boolean; 34 type: string; 35 translateY: number; 36 }, 37 row: TraceRow<ThreadSysCallStruct> 38 ): void { 39 let threadList = row.dataList; 40 let threadFilter = row.dataListCache; 41 dataFilterHandler(threadList, threadFilter, { 42 startKey: 'startTs', 43 durKey: 'dur', 44 startNS: TraceRow.range?.startNS ?? 0, 45 endNS: TraceRow.range?.endNS ?? 0, 46 totalNS: TraceRow.range?.totalNS ?? 0, 47 frame: row.frame, 48 paddingTop: 3, 49 useCache: threadReq.useCache || !(TraceRow.range?.refresh ?? false), 50 }); 51 drawLoadingFrame(threadReq.context, threadFilter, row); 52 threadReq.context.beginPath(); 53 let find: boolean = false; 54 for (let re of threadFilter) { 55 re.translateY = threadReq.translateY; 56 ThreadSysCallStruct.drawThread(threadReq.context, re); 57 if (row.isHover && re.frame && isFrameContainPoint(re.frame!, row.hoverX, row.hoverY)) { 58 ThreadSysCallStruct.hoverStruct = re; 59 find = true; 60 } 61 } 62 threadReq.context.closePath(); 63 } 64 65 render(threadReq: RequestMessage, threadList: Array<unknown>, threadFilter: Array<unknown>): void {} 66} 67 68export function ThreadSysCallStructOnClick( 69 clickRowType: string, 70 sp: SpSystemTrace, 71 entry?: ThreadSysCallStruct 72): Promise<unknown> { 73 return new Promise((resolve, reject) => { 74 if (clickRowType === TraceRow.ROW_TYPE_THREAD_SYS_CALL && (ThreadSysCallStruct.hoverStruct || entry)) { 75 ThreadSysCallStruct.selectStruct = entry || ThreadSysCallStruct.hoverStruct; 76 sp.timerShaftEL?.drawTriangle(ThreadSysCallStruct.selectStruct!.startTs || 0, 'inverted'); 77 sp.traceSheetEL?.displaySysCallData(ThreadSysCallStruct.selectStruct!); 78 sp.timerShaftEL?.modifyFlagList(undefined); 79 reject(new Error()); 80 } else { 81 resolve(null); 82 } 83 }); 84} 85export class ThreadSysCallStruct extends BaseStruct { 86 static hoverStruct: ThreadSysCallStruct | undefined; 87 static selectStruct: ThreadSysCallStruct | undefined; 88 name: string | undefined; 89 tid: number | undefined; 90 id: number | undefined; 91 pid: number | undefined; 92 itid: number | undefined; 93 startTs: number | undefined; 94 dur: number | undefined; 95 args: string | undefined; 96 ret: number | undefined; 97 98 static drawThread(threadContext: CanvasRenderingContext2D, data: ThreadSysCallStruct): void { 99 if (data.frame) { 100 threadContext.globalAlpha = 1; 101 threadContext.fillStyle = ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.name || '', 0, ColorUtils.FUNC_COLOR.length)]; 102 let textColor = ColorUtils.FUNC_COLOR[ColorUtils.hashFunc(data.name || '', 0, ColorUtils.FUNC_COLOR.length)]; 103 if (ThreadSysCallStruct.hoverStruct && data.name === ThreadSysCallStruct.hoverStruct.name) { 104 threadContext.globalAlpha = 0.7; 105 } 106 threadContext.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); 107 threadContext.fillStyle = ColorUtils.funcTextColor(textColor); 108 threadContext.textBaseline = 'middle'; 109 threadContext.font = '8px sans-serif'; 110 data.frame.width > 7 && data.name && drawString(threadContext, data.name, 2, data.frame, data); 111 if ( 112 ThreadSysCallStruct.selectStruct && 113 ThreadSysCallStruct.equals(ThreadSysCallStruct.selectStruct, data) 114 ) { 115 threadContext.strokeStyle = '#232c5d'; 116 threadContext.lineWidth = 2; 117 threadContext.strokeRect( 118 data.frame.x, 119 data.frame.y, 120 data.frame.width - 2, 121 data.frame.height 122 ); 123 } 124 } 125 } 126 127 static equals(d1: ThreadSysCallStruct, d2: ThreadSysCallStruct): boolean { 128 return ( 129 d1 && 130 d2 && 131 d1.tid === d2.tid && 132 d1.name === d2.name && 133 d1.startTs === d2.startTs && 134 d1.dur === d2.dur 135 ); 136 } 137} 138