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 isFrameContainPoint, 19 Rect, 20 Render, 21 RequestMessage, 22 drawString, 23 drawLoadingFrame, 24} from './ProcedureWorkerCommon'; 25import { TraceRow } from '../../component/trace/base/TraceRow'; 26import { Utils } from '../../component/trace/base/Utils'; 27import { ThreadStruct as BaseThreadStruct } from '../../bean/ThreadStruct'; 28import { SpSystemTrace } from '../../component/SpSystemTrace'; 29import { SpSegmentationChart } from '../../component/chart/SpSegmentationChart'; 30import { ns2x } from './ProcedureWorkerCommon'; 31import { Flag } from '../../component/trace/timer-shaft/Flag'; 32import { CpuFreqExtendStruct } from './ProcedureWorkerFreqExtend'; 33import { BinderStruct } from './procedureWorkerBinder'; 34import { TabPaneFreqStatesDataCut } from '../../component/trace/sheet/states/TabPaneFreqStatesDataCut'; 35export class ThreadRender extends Render { 36 renderMainThread( 37 threadReq: { 38 context: CanvasRenderingContext2D; 39 useCache: boolean; 40 type: string; 41 translateY: number; 42 }, 43 row: TraceRow<ThreadStruct> 44 ): void { 45 let threadList = row.dataList; 46 let threadFilter = row.dataListCache; 47 dataFilterHandler(threadList, threadFilter, { 48 startKey: 'startTime', 49 durKey: 'dur', 50 startNS: TraceRow.range?.startNS ?? 0, 51 endNS: TraceRow.range?.endNS ?? 0, 52 totalNS: TraceRow.range?.totalNS ?? 0, 53 frame: row.frame, 54 paddingTop: 3, 55 useCache: threadReq.useCache || !(TraceRow.range?.refresh ?? false), 56 }); 57 drawLoadingFrame(threadReq.context, threadFilter, row); 58 threadReq.context.beginPath(); 59 let find: boolean = false; 60 for (let re of threadFilter) { 61 re.translateY = threadReq.translateY; 62 ThreadStruct.drawThread(threadReq.context, re); 63 if (row.isHover && re.frame && isFrameContainPoint(re.frame!, row.hoverX, row.hoverY)) { 64 ThreadStruct.hoverThreadStruct = re; 65 find = true; 66 } 67 } 68 threadReq.context.closePath(); 69 } 70 71 render(threadReq: RequestMessage, threadList: Array<unknown>, threadFilter: Array<unknown>): void {} 72} 73 74export function ThreadStructOnClick( 75 clickRowType: string, 76 sp: SpSystemTrace, 77 threadClickHandler: unknown, 78 cpuClickHandler: unknown, 79 prioClickHandlerFunc: unknown, 80 entry?: ThreadStruct 81): Promise<unknown> { 82 return new Promise((resolve, reject) => { 83 if (clickRowType === TraceRow.ROW_TYPE_THREAD && (ThreadStruct.hoverThreadStruct || entry)) { 84 sp.removeLinkLinesByBusinessType('thread'); 85 ThreadStruct.selectThreadStruct = entry || ThreadStruct.hoverThreadStruct; 86 sp.timerShaftEL?.drawTriangle(ThreadStruct.selectThreadStruct!.startTime || 0, 'inverted'); 87 sp.traceSheetEL?.displayThreadData(ThreadStruct.selectThreadStruct!, 88 //@ts-ignore 89 threadClickHandler, cpuClickHandler, prioClickHandlerFunc); 90 sp.timerShaftEL?.modifyFlagList(undefined); 91 reject(new Error()); 92 } else { 93 resolve(null); 94 } 95 }); 96} 97export class ThreadStruct extends BaseThreadStruct { 98 static otherColor = '#673ab7'; 99 static uninterruptibleSleepColor = '#f19d38'; 100 static uninterruptibleSleepNonIOColor = '#795548'; 101 static traceColor = '#0d47a1'; 102 static sColor = '#FBFBFB'; 103 static hoverThreadStruct: ThreadStruct | undefined; 104 static selectThreadStruct: ThreadStruct | undefined; 105 static selectThreadStructList: Array<ThreadStruct> = []; 106 static firstselectThreadStruct: ThreadStruct | undefined; 107 static isClickPrio: boolean = false; 108 static prioCount: Array<unknown> = []; 109 argSetID: number | undefined; 110 translateY: number | undefined; 111 textMetricsWidth: number | undefined; 112 static startCycleTime: number = 0; 113 static endTime: number = 0; 114 115 static drawThread(threadContext: CanvasRenderingContext2D, data: ThreadStruct): void { 116 if (data.frame) { 117 118 threadContext.globalAlpha = 1; 119 let stateText = ThreadStruct.getEndState(data.state || ''); 120 threadContext.fillStyle = Utils.getStateColor(data.state || ''); 121 if ('S' === data.state) { 122 threadContext.globalAlpha = 0.2; 123 }; 124 threadContext.fillRect(data.frame.x, data.frame.y, data.frame.width, data.frame.height); 125 threadContext.fillStyle = '#fff'; 126 threadContext.textBaseline = 'middle'; 127 threadContext.font = '8px sans-serif'; 128 data.frame.width > 7 && drawString(threadContext, stateText, 2, data.frame, data); 129 if ( 130 ThreadStruct.selectThreadStruct && 131 ThreadStruct.equals(ThreadStruct.selectThreadStruct, data) && 132 data.state !== 'S' 133 ) { 134 threadContext.strokeStyle = '#232c5d'; 135 threadContext.lineWidth = 2; 136 threadContext.strokeRect( 137 data.frame.x, 138 data.frame.y, 139 data.frame.width - 2, 140 data.frame.height 141 ); 142 } 143 if (!ThreadStruct.selectThreadStruct) { 144 ThreadStruct.isClickPrio = false; 145 } 146 } 147 } 148} 149