1 /* 2 * Copyright 2014 The Chromium Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 /** 8 * @constructor 9 * @extends {WebInspector.VBox} 10 */ 11 WebInspector.TimelineLayersView = function() 12 { 13 WebInspector.VBox.call(this); 14 15 this._paintTiles = []; 16 this._layers3DView = new WebInspector.Layers3DView(); 17 this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.ObjectSelected, this._onObjectSelected, this); 18 this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.ObjectHovered, this._onObjectHovered, this); 19 this._layers3DView.addEventListener(WebInspector.Layers3DView.Events.JumpToPaintEventRequested, this._jumpToPaintEvent, this); 20 this._layers3DView.show(this.element); 21 } 22 23 WebInspector.TimelineLayersView.prototype = { 24 /** 25 * @param {!WebInspector.DeferredLayerTree} deferredLayerTree 26 * @param {?Array.<!WebInspector.LayerPaintEvent>} paints 27 */ 28 showLayerTree: function(deferredLayerTree, paints) 29 { 30 this._disposeTiles(); 31 this._deferredLayerTree = deferredLayerTree; 32 this._paints = paints; 33 if (this.isShowing()) 34 this._update(); 35 else 36 this._updateWhenVisible = true; 37 }, 38 39 wasShown: function() 40 { 41 if (this._updateWhenVisible) { 42 this._updateWhenVisible = false; 43 this._update(); 44 } 45 }, 46 47 /** 48 * @param {!WebInspector.TimelineModel} model 49 * @param {!WebInspector.TimelineModeViewDelegate} delegate 50 */ 51 setTimelineModelAndDelegate: function(model, delegate) 52 { 53 this._model = model; 54 this._delegate = delegate; 55 }, 56 57 /** 58 * @param {!WebInspector.Event} event 59 */ 60 _jumpToPaintEvent: function(event) 61 { 62 var traceEvent = event.data; 63 var eventRecord; 64 65 /** 66 * @param {!WebInspector.TimelineModel.Record} record 67 * @return {boolean} 68 */ 69 function findRecordWithEvent(record) 70 { 71 if (record.traceEvent() === traceEvent) { 72 eventRecord = record; 73 return true; 74 } 75 return false; 76 } 77 78 this._model.forAllRecords(findRecordWithEvent); 79 if (eventRecord) { 80 var selection = WebInspector.TimelineSelection.fromRecord(eventRecord); 81 this._delegate.select(selection); 82 } 83 }, 84 85 _update: function() 86 { 87 var layerTree; 88 89 this._target = this._deferredLayerTree.target(); 90 var originalTiles = this._paintTiles; 91 var tilesReadyBarrier = new CallbackBarrier(); 92 this._deferredLayerTree.resolve(tilesReadyBarrier.createCallback(onLayersReady)); 93 for (var i = 0; this._paints && i < this._paints.length; ++i) 94 this._paints[i].loadPicture(tilesReadyBarrier.createCallback(onSnapshotLoaded.bind(this, this._paints[i]))); 95 tilesReadyBarrier.callWhenDone(onLayersAndTilesReady.bind(this)); 96 97 /** 98 * @param {!WebInspector.LayerTreeBase} resolvedLayerTree 99 */ 100 function onLayersReady(resolvedLayerTree) 101 { 102 layerTree = resolvedLayerTree; 103 } 104 105 /** 106 * @param {!WebInspector.LayerPaintEvent} paintEvent 107 * @param {?Array.<number>} rect 108 * @param {?WebInspector.PaintProfilerSnapshot} snapshot 109 * @this {WebInspector.TimelineLayersView} 110 */ 111 function onSnapshotLoaded(paintEvent, rect, snapshot) 112 { 113 if (!rect || !snapshot) 114 return; 115 // We're too late and there's a new generation of tiles being loaded. 116 if (originalTiles !== this._paintTiles) { 117 snapshot.dispose(); 118 return; 119 } 120 this._paintTiles.push({layerId: paintEvent.layerId(), rect: rect, snapshot: snapshot, traceEvent: paintEvent.event()}); 121 } 122 123 /** 124 * @this {WebInspector.TimelineLayersView} 125 */ 126 function onLayersAndTilesReady() 127 { 128 this._layers3DView.setLayerTree(layerTree); 129 this._layers3DView.setTiles(this._paintTiles); 130 } 131 }, 132 133 /** 134 * @param {?WebInspector.Layers3DView.ActiveObject} activeObject 135 */ 136 _selectObject: function(activeObject) 137 { 138 var layer = activeObject && activeObject.layer; 139 if (this._currentlySelectedLayer === activeObject) 140 return; 141 this._currentlySelectedLayer = activeObject; 142 this._toggleNodeHighlight(layer ? layer.nodeForSelfOrAncestor() : null); 143 this._layers3DView.selectObject(activeObject); 144 }, 145 146 /** 147 * @param {?WebInspector.Layers3DView.ActiveObject} activeObject 148 */ 149 _hoverObject: function(activeObject) 150 { 151 var layer = activeObject && activeObject.layer; 152 if (this._currentlyHoveredLayer === activeObject) 153 return; 154 this._currentlyHoveredLayer = activeObject; 155 this._toggleNodeHighlight(layer ? layer.nodeForSelfOrAncestor() : null); 156 this._layers3DView.hoverObject(activeObject); 157 }, 158 159 /** 160 * @param {?WebInspector.DOMNode} node 161 */ 162 _toggleNodeHighlight: function(node) 163 { 164 if (node) { 165 node.highlightForTwoSeconds(); 166 return; 167 } 168 if (this._target) 169 this._target.domModel.hideDOMNodeHighlight(); 170 171 }, 172 173 /** 174 * @param {!WebInspector.Event} event 175 */ 176 _onObjectSelected: function(event) 177 { 178 var activeObject = /** @type {!WebInspector.Layers3DView.ActiveObject} */ (event.data); 179 this._selectObject(activeObject); 180 }, 181 182 /** 183 * @param {!WebInspector.Event} event 184 */ 185 _onObjectHovered: function(event) 186 { 187 var activeObject = /** @type {!WebInspector.Layers3DView.ActiveObject} */ (event.data); 188 this._hoverObject(activeObject); 189 }, 190 191 _disposeTiles: function() 192 { 193 for (var i = 0; i < this._paintTiles.length; ++i) 194 this._paintTiles[i].snapshot.dispose(); 195 this._paintTiles = []; 196 }, 197 198 __proto__: WebInspector.VBox.prototype 199 } 200