Home | History | Annotate | Download | only in timeline
      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