TracingLayerTree.js 6.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. export class TracingLayerTree extends SDK.LayerTreeBase{constructor(target){super(target);this._tileById=new Map();this._paintProfilerModel=target&&target.model(SDK.PaintProfilerModel);}
  2. async setLayers(root,layers,paints){const idsToResolve=new Set();if(root){this._extractNodeIdsToResolve(idsToResolve,{},root);}else{for(let i=0;i<layers.length;++i){this._extractNodeIdsToResolve(idsToResolve,{},layers[i]);}}
  3. await this.resolveBackendNodeIds(idsToResolve);const oldLayersById=this._layersById;this._layersById={};this.setContentRoot(null);if(root){const convertedLayers=this._innerSetLayers(oldLayersById,root);this.setRoot(convertedLayers);}else{const processedLayers=layers.map(this._innerSetLayers.bind(this,oldLayersById));const contentRoot=this.contentRoot();this.setRoot(contentRoot);for(let i=0;i<processedLayers.length;++i){if(processedLayers[i].id()!==contentRoot.id()){contentRoot.addChild(processedLayers[i]);}}}
  4. this._setPaints(paints);}
  5. setTiles(tiles){this._tileById=new Map();for(const tile of tiles){this._tileById.set(tile.id,tile);}}
  6. pictureForRasterTile(tileId){const tile=this._tileById.get('cc::Tile/'+tileId);if(!tile){Common.console.error(`Tile ${tileId} is missing`);return(Promise.resolve(null));}
  7. const layer=(this.layerById(tile.layer_id));if(!layer){Common.console.error(`Layer ${tile.layer_id} for tile ${tileId} is not found`);return(Promise.resolve(null));}
  8. return layer._pictureForRect(tile.content_rect);}
  9. _setPaints(paints){for(let i=0;i<paints.length;++i){const layer=this._layersById[paints[i].layerId()];if(layer){layer._addPaintEvent(paints[i]);}}}
  10. _innerSetLayers(oldLayersById,payload){let layer=(oldLayersById[payload.layer_id]);if(layer){layer._reset(payload);}else{layer=new TracingLayer(this._paintProfilerModel,payload);}
  11. this._layersById[payload.layer_id]=layer;if(payload.owner_node){layer._setNode(this.backendNodeIdToNode().get(payload.owner_node)||null);}
  12. if(!this.contentRoot()&&layer.drawsContent()){this.setContentRoot(layer);}
  13. for(let i=0;payload.children&&i<payload.children.length;++i){layer.addChild(this._innerSetLayers(oldLayersById,payload.children[i]));}
  14. return layer;}
  15. _extractNodeIdsToResolve(nodeIdsToResolve,seenNodeIds,payload){const backendNodeId=payload.owner_node;if(backendNodeId&&!this.backendNodeIdToNode().has(backendNodeId)){nodeIdsToResolve.add(backendNodeId);}
  16. for(let i=0;payload.children&&i<payload.children.length;++i){this._extractNodeIdsToResolve(nodeIdsToResolve,seenNodeIds,payload.children[i]);}}}
  17. export class TracingLayer{constructor(paintProfilerModel,payload){this._paintProfilerModel=paintProfilerModel;this._reset(payload);}
  18. _reset(payload){this._node=null;this._layerId=String(payload.layer_id);this._offsetX=payload.position[0];this._offsetY=payload.position[1];this._width=payload.bounds.width;this._height=payload.bounds.height;this._children=[];this._parentLayerId=null;this._parent=null;this._quad=payload.layer_quad||[];this._createScrollRects(payload);this._compositingReasons=payload.compositing_reasons||(payload.debug_info&&payload.debug_info.compositing_reasons)||[];this._drawsContent=!!payload.draws_content;this._gpuMemoryUsage=payload.gpu_memory_usage;this._paints=[];}
  19. id(){return this._layerId;}
  20. parentId(){return this._parentLayerId;}
  21. parent(){return this._parent;}
  22. isRoot(){return!this.parentId();}
  23. children(){return this._children;}
  24. addChild(childParam){const child=(childParam);if(child._parent){console.assert(false,'Child already has a parent');}
  25. this._children.push(child);child._parent=this;child._parentLayerId=this._layerId;}
  26. _setNode(node){this._node=node;}
  27. node(){return this._node;}
  28. nodeForSelfOrAncestor(){for(let layer=this;layer;layer=layer._parent){if(layer._node){return layer._node;}}
  29. return null;}
  30. offsetX(){return this._offsetX;}
  31. offsetY(){return this._offsetY;}
  32. width(){return this._width;}
  33. height(){return this._height;}
  34. transform(){return null;}
  35. quad(){return this._quad;}
  36. anchorPoint(){return[0.5,0.5,0];}
  37. invisible(){return false;}
  38. paintCount(){return 0;}
  39. lastPaintRect(){return null;}
  40. scrollRects(){return this._scrollRects;}
  41. stickyPositionConstraint(){return null;}
  42. gpuMemoryUsage(){return this._gpuMemoryUsage;}
  43. snapshots(){return this._paints.map(paint=>paint.snapshotPromise().then(snapshot=>{if(!snapshot){return null;}
  44. const rect={x:snapshot.rect[0],y:snapshot.rect[1],width:snapshot.rect[2],height:snapshot.rect[3]};return{rect:rect,snapshot:snapshot.snapshot};}));}
  45. _pictureForRect(targetRect){return Promise.all(this._paints.map(paint=>paint.picturePromise())).then(pictures=>{const fragments=pictures.filter(picture=>picture&&rectsOverlap(picture.rect,targetRect)).map(picture=>({x:picture.rect[0],y:picture.rect[1],picture:picture.serializedPicture}));if(!fragments.length||!this._paintProfilerModel){return null;}
  46. const x0=fragments.reduce((min,item)=>Math.min(min,item.x),Infinity);const y0=fragments.reduce((min,item)=>Math.min(min,item.y),Infinity);const rect={x:targetRect[0]-x0,y:targetRect[1]-y0,width:targetRect[2],height:targetRect[3]};return this._paintProfilerModel.loadSnapshotFromFragments(fragments).then(snapshot=>snapshot?{rect:rect,snapshot:snapshot}:null);});function segmentsOverlap(a1,a2,b1,b2){console.assert(a1<=a2&&b1<=b2,'segments should be specified as ordered pairs');return a2>b1&&a1<b2;}
  47. function rectsOverlap(a,b){return segmentsOverlap(a[0],a[0]+a[2],b[0],b[0]+b[2])&&segmentsOverlap(a[1],a[1]+a[3],b[1],b[1]+b[3]);}}
  48. _scrollRectsFromParams(params,type){return{rect:{x:params[0],y:params[1],width:params[2],height:params[3]},type:type};}
  49. _createScrollRects(payload){this._scrollRects=[];if(payload.non_fast_scrollable_region){this._scrollRects.push(this._scrollRectsFromParams(payload.non_fast_scrollable_region,SDK.Layer.ScrollRectType.NonFastScrollable.name));}
  50. if(payload.touch_event_handler_region){this._scrollRects.push(this._scrollRectsFromParams(payload.touch_event_handler_region,SDK.Layer.ScrollRectType.TouchEventHandler.name));}
  51. if(payload.wheel_event_handler_region){this._scrollRects.push(this._scrollRectsFromParams(payload.wheel_event_handler_region,SDK.Layer.ScrollRectType.WheelEventHandler.name));}
  52. if(payload.scroll_event_handler_region){this._scrollRects.push(this._scrollRectsFromParams(payload.scroll_event_handler_region,SDK.Layer.ScrollRectType.RepaintsOnScroll.name));}}
  53. _addPaintEvent(paint){this._paints.push(paint);}
  54. requestCompositingReasons(){return Promise.resolve(this._compositingReasons);}
  55. drawsContent(){return this._drawsContent;}}
  56. self.TimelineModel=self.TimelineModel||{};TimelineModel=TimelineModel||{};TimelineModel.TracingLayerTree=TracingLayerTree;TimelineModel.TracingLayer=TracingLayer;TimelineModel.TracingLayerPayload;TimelineModel.TracingLayerTile;