UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

1 lines 9.71 kB
import*as Platform from"../../core/platform/platform.js";import*as SDK from"../../core/sdk/sdk.js";import*as TraceEngine from"../trace/trace.js";import{RecordType,EventOnTimelineData}from"./TimelineModel.js";import{TracingLayerTree}from"./TracingLayerTree.js";export class TimelineFrameModel{categoryMapper;frames;frameById;beginFrameQueue;minimumRecordTime;lastFrame;mainFrameCommitted;mainFrameRequested;lastLayerTree;framePendingActivation;currentTaskTimeByCategory;target;framePendingCommit;lastBeginFrame;lastDroppedFrame;lastNeedsBeginFrame;lastTaskBeginTime;layerTreeId;currentProcessMainThread;constructor(e){this.categoryMapper=e,this.reset()}getFrames(){return this.frames}getFramesWithinWindow(e,t){const a=Platform.ArrayUtilities.lowerBound(this.frames,e||0,((e,t)=>e-t.endTime)),r=Platform.ArrayUtilities.lowerBound(this.frames,t||1/0,((e,t)=>e-t.startTime));return this.frames.slice(a,r)}hasRasterTile(e){const t=e.args.tileData;if(!t)return!1;const a=t.sourceFrameNumber,r=a&&this.frameById[a];return!(!r||!r.layerTree)}rasterTilePromise(e){if(!this.target)return Promise.resolve(null);const t=e.args.tileData,a=t.sourceFrameNumber,r=t.tileId&&t.tileId.id_ref,i=a&&this.frameById[a];return i&&i.layerTree&&r?i.layerTree.layerTreePromise().then((e=>e&&e.pictureForRasterTile(r))):Promise.resolve(null)}reset(){this.minimumRecordTime=1/0,this.frames=[],this.frameById={},this.beginFrameQueue=new TimelineFrameBeginFrameQueue,this.lastFrame=null,this.lastLayerTree=null,this.mainFrameCommitted=!1,this.mainFrameRequested=!1,this.framePendingCommit=null,this.lastBeginFrame=null,this.lastDroppedFrame=null,this.lastNeedsBeginFrame=null,this.framePendingActivation=null,this.lastTaskBeginTime=null,this.target=null,this.layerTreeId=null,this.currentTaskTimeByCategory={}}handleBeginFrame(e,t){this.lastFrame||this.startFrame(e),this.lastBeginFrame=e,this.beginFrameQueue.addFrameIfNotExists(t,e,!1,!1)}handleDroppedFrame(e,t,a){this.lastFrame||this.startFrame(e),this.beginFrameQueue.addFrameIfNotExists(t,e,!0,a),this.beginFrameQueue.setDropped(t,!0),this.beginFrameQueue.setPartial(t,a)}handleDrawFrame(e,t){if(this.lastFrame){if(this.mainFrameCommitted||!this.mainFrameRequested){if(this.lastNeedsBeginFrame){(this.framePendingActivation?this.framePendingActivation.triggerTime:this.lastBeginFrame||this.lastNeedsBeginFrame)>this.lastFrame.startTime&&(this.lastFrame.idle=!0,this.lastBeginFrame=null),this.lastNeedsBeginFrame=null}const e=this.beginFrameQueue.processPendingBeginFramesOnDrawFrame(t);for(const t of e){const e=this.lastFrame.idle;this.startFrame(t.startTime),e&&this.framePendingActivation&&this.commitPendingFrame(),t.isDropped&&(this.lastFrame.dropped=!0),t.isPartial&&(this.lastFrame.isPartial=!0)}}this.mainFrameCommitted=!1}else this.startFrame(e)}handleActivateLayerTree(){this.lastFrame&&this.framePendingActivation&&!this.lastNeedsBeginFrame&&this.commitPendingFrame()}handleRequestMainThreadFrame(){this.lastFrame&&(this.mainFrameRequested=!0)}handleCommit(){this.framePendingCommit&&(this.framePendingActivation=this.framePendingCommit,this.framePendingCommit=null,this.mainFrameRequested=!1,this.mainFrameCommitted=!0)}handleLayerTreeSnapshot(e){this.lastLayerTree=e}handleNeedFrameChanged(e,t){t&&(this.lastNeedsBeginFrame=e)}startFrame(e){this.lastFrame&&this.flushFrame(this.lastFrame,e),this.lastFrame=new TimelineFrame(e,e-this.minimumRecordTime)}flushFrame(e,t){e.setLayerTree(this.lastLayerTree),e.setEndTime(t),this.lastLayerTree&&this.lastLayerTree.setPaints(e.paints);const a=this.frames[this.frames.length-1];this.frames.length&&a&&(e.startTime!==a.endTime||e.startTime>e.endTime)&&console.assert(!1,`Inconsistent frame time for frame ${this.frames.length} (${e.startTime} - ${e.endTime})`),this.frames.push(e),"number"==typeof e.mainFrameId&&(this.frameById[e.mainFrameId]=e)}commitPendingFrame(){this.framePendingActivation&&this.lastFrame&&(this.lastFrame.addTimeForCategories(this.framePendingActivation.timeByCategory),this.lastFrame.paints=this.framePendingActivation.paints,this.lastFrame.mainFrameId=this.framePendingActivation.mainFrameId,this.framePendingActivation=null)}addTraceEvents(e,t,a){this.target=e;let r=0;this.currentProcessMainThread=a.length&&a[0].thread||null;for(let e=0;e<t.length;++e){for(;r+1<a.length&&a[r+1].time<=t[e].startTime;)this.currentProcessMainThread=a[++r].thread;this.addTraceEvent(t[e])}this.currentProcessMainThread=null}addTraceEvent(e){if(e.startTime&&e.startTime<this.minimumRecordTime&&(this.minimumRecordTime=e.startTime),e.name===RecordType.SetLayerTreeId)this.layerTreeId=e.args.layerTreeId||e.args.data.layerTreeId;else if(e.id&&"O"===e.phase&&e.name===RecordType.LayerTreeHostImplSnapshot&&Number(e.id)===this.layerTreeId&&this.target){const t=e;this.handleLayerTreeSnapshot(new TracingFrameLayerTree(this.target,t))}else this.processCompositorEvents(e),e.thread===this.currentProcessMainThread?this.addMainThreadTraceEvent(e):this.lastFrame&&e.selfTime&&!TraceEngine.Legacy.TracingModel.isTopLevelEvent(e)&&this.lastFrame.addTimeForCategory(this.categoryMapper(e),e.selfTime)}processCompositorEvents(e){if(e.args.layerTreeId!==this.layerTreeId)return;const t=e.startTime;e.name===RecordType.BeginFrame?this.handleBeginFrame(t,e.args.frameSeqId):e.name===RecordType.DrawFrame?this.handleDrawFrame(t,e.args.frameSeqId):e.name===RecordType.ActivateLayerTree?this.handleActivateLayerTree():e.name===RecordType.RequestMainThreadFrame?this.handleRequestMainThreadFrame():e.name===RecordType.NeedsBeginFrameChanged?this.handleNeedFrameChanged(t,e.args.data&&e.args.data.needsBeginFrame):e.name===RecordType.DroppedFrame&&this.handleDroppedFrame(t,e.args.frameSeqId,e.args.hasPartialUpdate)}addMainThreadTraceEvent(e){TraceEngine.Legacy.TracingModel.isTopLevelEvent(e)&&(this.currentTaskTimeByCategory={},this.lastTaskBeginTime=e.startTime),!this.framePendingCommit&&TimelineFrameModel.mainFrameMarkers.indexOf(e.name)>=0&&(this.framePendingCommit=new PendingFrame(this.lastTaskBeginTime||e.startTime,this.currentTaskTimeByCategory)),this.framePendingCommit?(this.addTimeForCategory(this.framePendingCommit.timeByCategory,e),e.name===RecordType.BeginMainThreadFrame&&e.args.data&&e.args.data.frameId&&(this.framePendingCommit.mainFrameId=e.args.data.frameId),e.name===RecordType.Paint&&e.args.data.layerId&&EventOnTimelineData.forEvent(e).picture&&this.target&&this.framePendingCommit.paints.push(new LayerPaintEvent(e,this.target)),e.name!==RecordType.CompositeLayers&&e.name!==RecordType.Commit||e.args.layerTreeId!==this.layerTreeId||this.handleCommit()):this.addTimeForCategory(this.currentTaskTimeByCategory,e)}addTimeForCategory(e,t){if(!t.selfTime)return;const a=this.categoryMapper(t);e[a]=(e[a]||0)+t.selfTime}static mainFrameMarkers=[RecordType.ScheduleStyleRecalculation,RecordType.InvalidateLayout,RecordType.BeginMainThreadFrame,RecordType.ScrollLayer]}export class TracingFrameLayerTree{target;snapshot;paintsInternal;constructor(e,t){this.target=e,this.snapshot=t}async layerTreePromise(){const e=this.snapshot.getSnapshot();if(!e)return null;const t=e.device_viewport_size,a=e.active_tiles,r=e.active_tree.root_layer,i=e.active_tree.layers,s=new TracingLayerTree(this.target);return s.setViewportSize(t),s.setTiles(a),await s.setLayers(r,i,this.paintsInternal||[]),s}paints(){return this.paintsInternal||[]}setPaints(e){this.paintsInternal=e}}export class TimelineFrame{startTime;startTimeOffset;endTime;duration;timeByCategory;cpuTime;idle;dropped;isPartial;layerTree;paints;mainFrameId;constructor(e,t){this.startTime=e,this.startTimeOffset=t,this.endTime=this.startTime,this.duration=0,this.timeByCategory={},this.cpuTime=0,this.idle=!1,this.dropped=!1,this.isPartial=!1,this.layerTree=null,this.paints=[],this.mainFrameId=void 0}setEndTime(e){this.endTime=e,this.duration=this.endTime-this.startTime}setLayerTree(e){this.layerTree=e}addTimeForCategories(e){for(const t in e)this.addTimeForCategory(t,e[t])}addTimeForCategory(e,t){this.timeByCategory[e]=(this.timeByCategory[e]||0)+t,this.cpuTime+=t}}export class LayerPaintEvent{eventInternal;target;constructor(e,t){this.eventInternal=e,this.target=t}layerId(){return this.eventInternal.args.data.layerId}event(){return this.eventInternal}picturePromise(){const e=EventOnTimelineData.forEvent(this.eventInternal).picture;if(!e)return Promise.resolve(null);const t=e.getSnapshot(),a=t.params&&t.params.layer_rect,r=t.skp64;return Promise.resolve(a&&r?{rect:a,serializedPicture:r}:null)}async snapshotPromise(){const e=this.target&&this.target.model(SDK.PaintProfiler.PaintProfilerModel),t=await this.picturePromise();if(!t||!e)return null;const a=await e.loadSnapshot(t.serializedPicture);return a?{rect:t.rect,snapshot:a}:null}}export class PendingFrame{timeByCategory;paints;mainFrameId;triggerTime;constructor(e,t){this.timeByCategory=t,this.paints=[],this.mainFrameId=void 0,this.triggerTime=e}}class BeginFrameInfo{seqId;startTime;isDropped;isPartial;constructor(e,t,a,r){this.seqId=e,this.startTime=t,this.isDropped=a,this.isPartial=r}}export class TimelineFrameBeginFrameQueue{queueFrames;mapFrames;constructor(){this.queueFrames=[],this.mapFrames={}}addFrameIfNotExists(e,t,a,r){e in this.mapFrames||(this.mapFrames[e]=new BeginFrameInfo(e,t,a,r),this.queueFrames.push(e))}setDropped(e,t){e in this.mapFrames&&(this.mapFrames[e].isDropped=t)}setPartial(e,t){e in this.mapFrames&&(this.mapFrames[e].isPartial=t)}processPendingBeginFramesOnDrawFrame(e){const t=[];if(e in this.mapFrames){for(;this.queueFrames[0]!==e;){const e=this.queueFrames[0];this.mapFrames[e].isDropped&&t.push(this.mapFrames[e]),delete this.mapFrames[e],this.queueFrames.shift()}t.push(this.mapFrames[e]),delete this.mapFrames[e],this.queueFrames.shift()}return t}}