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 BaseStruct, 18 dataFilterHandler, 19 isFrameContainPoint, 20 Rect, 21 Render, 22 RequestMessage, 23 drawString, 24} from './ProcedureWorkerCommon.js'; 25import { TraceRow } from '../../component/trace/base/TraceRow.js'; 26import { Utils } from '../../component/trace/base/Utils.js'; 27import { ThreadStruct as BaseThreadStruct } from '../../bean/ThreadStruct.js'; 28export class ThreadRender extends Render { 29 renderMainThread( 30 threadReq: { 31 context: CanvasRenderingContext2D; 32 useCache: boolean; 33 type: string; 34 translateY: number; 35 }, 36 row: TraceRow<ThreadStruct> 37 ) { 38 let threadList = row.dataList; 39 let threadFilter = row.dataListCache; 40 dataFilterHandler(threadList, threadFilter, { 41 startKey: 'startTime', 42 durKey: 'dur', 43 startNS: TraceRow.range?.startNS ?? 0, 44 endNS: TraceRow.range?.endNS ?? 0, 45 totalNS: TraceRow.range?.totalNS ?? 0, 46 frame: row.frame, 47 paddingTop: 5, 48 useCache: threadReq.useCache || !(TraceRow.range?.refresh ?? false), 49 }); 50 threadReq.context.beginPath(); 51 for (let re of threadFilter) { 52 re.translateY = threadReq.translateY; 53 ThreadStruct.drawThread(threadReq.context, re); 54 if (row.isHover && re.frame && isFrameContainPoint(re.frame!, row.hoverX, row.hoverY)) { 55 ThreadStruct.hoverThreadStruct = re; 56 } 57 } 58 threadReq.context.closePath(); 59 } 60 61 render(threadReq: RequestMessage, threadList: Array<any>, threadFilter: Array<any>) {} 62} 63 64const padding = 3; 65 66export class ThreadStruct extends BaseThreadStruct { 67 static otherColor = '#673ab7'; 68 static uninterruptibleSleepColor = '#f19d38'; 69 static uninterruptibleSleepNonIOColor = '#795548'; 70 static traceColor = '#0d47a1'; 71 static sColor = '#FBFBFB'; 72 static hoverThreadStruct: ThreadStruct | undefined; 73 static selectThreadStruct: ThreadStruct | undefined; 74 argSetID: number | undefined; 75 translateY: number | undefined; 76 textMetricsWidth: number | undefined; 77 78 static drawThread(threadContext: CanvasRenderingContext2D, data: ThreadStruct) { 79 if (data.frame) { 80 threadContext.globalAlpha = 1; 81 let stateText = ThreadStruct.getEndState(data.state || ''); 82 threadContext.fillStyle = Utils.getStateColor(data.state || ''); 83 if ('S' === data.state) { 84 threadContext.globalAlpha = 0.2; 85 } 86 threadContext.fillRect(data.frame.x, data.frame.y + padding, data.frame.width, data.frame.height - padding * 2); 87 threadContext.fillStyle = '#fff'; 88 threadContext.textBaseline = 'middle'; 89 threadContext.font = '8px sans-serif'; 90 if ('S' !== data.state) { 91 data.frame.width > 7 && drawString(threadContext, stateText, 2, data.frame, data); 92 } 93 if ( 94 ThreadStruct.selectThreadStruct && 95 ThreadStruct.equals(ThreadStruct.selectThreadStruct, data) && 96 ThreadStruct.selectThreadStruct.state != 'S' 97 ) { 98 threadContext.strokeStyle = '#232c5d'; 99 threadContext.lineWidth = 2; 100 threadContext.strokeRect( 101 data.frame.x, 102 data.frame.y + padding, 103 data.frame.width - 2, 104 data.frame.height - padding * 2 105 ); 106 } 107 } 108 } 109} 110